diff options
Diffstat (limited to 'kernel/auditsc.c')
-rw-r--r-- | kernel/auditsc.c | 49 |
1 files changed, 43 insertions, 6 deletions
diff --git a/kernel/auditsc.c b/kernel/auditsc.c index c75522a83678..072566dd0caf 100644 --- a/kernel/auditsc.c +++ b/kernel/auditsc.c | |||
@@ -72,6 +72,8 @@ | |||
72 | #include <linux/fs_struct.h> | 72 | #include <linux/fs_struct.h> |
73 | #include <linux/compat.h> | 73 | #include <linux/compat.h> |
74 | #include <linux/ctype.h> | 74 | #include <linux/ctype.h> |
75 | #include <linux/string.h> | ||
76 | #include <uapi/linux/limits.h> | ||
75 | 77 | ||
76 | #include "audit.h" | 78 | #include "audit.h" |
77 | 79 | ||
@@ -1861,8 +1863,7 @@ void __audit_inode(struct filename *name, const struct dentry *dentry, | |||
1861 | } | 1863 | } |
1862 | 1864 | ||
1863 | list_for_each_entry_reverse(n, &context->names_list, list) { | 1865 | list_for_each_entry_reverse(n, &context->names_list, list) { |
1864 | /* does the name pointer match? */ | 1866 | if (!n->name || strcmp(n->name->name, name->name)) |
1865 | if (!n->name || n->name->name != name->name) | ||
1866 | continue; | 1867 | continue; |
1867 | 1868 | ||
1868 | /* match the correct record type */ | 1869 | /* match the correct record type */ |
@@ -1877,12 +1878,48 @@ void __audit_inode(struct filename *name, const struct dentry *dentry, | |||
1877 | } | 1878 | } |
1878 | 1879 | ||
1879 | out_alloc: | 1880 | out_alloc: |
1880 | /* unable to find the name from a previous getname(). Allocate a new | 1881 | /* unable to find an entry with both a matching name and type */ |
1881 | * anonymous entry. | 1882 | n = audit_alloc_name(context, AUDIT_TYPE_UNKNOWN); |
1882 | */ | ||
1883 | n = audit_alloc_name(context, AUDIT_TYPE_NORMAL); | ||
1884 | if (!n) | 1883 | if (!n) |
1885 | return; | 1884 | return; |
1885 | /* unfortunately, while we may have a path name to record with the | ||
1886 | * inode, we can't always rely on the string lasting until the end of | ||
1887 | * the syscall so we need to create our own copy, it may fail due to | ||
1888 | * memory allocation issues, but we do our best */ | ||
1889 | if (name) { | ||
1890 | /* we can't use getname_kernel() due to size limits */ | ||
1891 | size_t len = strlen(name->name) + 1; | ||
1892 | struct filename *new = __getname(); | ||
1893 | |||
1894 | if (unlikely(!new)) | ||
1895 | goto out; | ||
1896 | |||
1897 | if (len <= (PATH_MAX - sizeof(*new))) { | ||
1898 | new->name = (char *)(new) + sizeof(*new); | ||
1899 | new->separate = false; | ||
1900 | } else if (len <= PATH_MAX) { | ||
1901 | /* this looks odd, but is due to final_putname() */ | ||
1902 | struct filename *new2; | ||
1903 | |||
1904 | new2 = kmalloc(sizeof(*new2), GFP_KERNEL); | ||
1905 | if (unlikely(!new2)) { | ||
1906 | __putname(new); | ||
1907 | goto out; | ||
1908 | } | ||
1909 | new2->name = (char *)new; | ||
1910 | new2->separate = true; | ||
1911 | new = new2; | ||
1912 | } else { | ||
1913 | /* we should never get here, but let's be safe */ | ||
1914 | __putname(new); | ||
1915 | goto out; | ||
1916 | } | ||
1917 | strlcpy((char *)new->name, name->name, len); | ||
1918 | new->uptr = NULL; | ||
1919 | new->aname = n; | ||
1920 | n->name = new; | ||
1921 | n->name_put = true; | ||
1922 | } | ||
1886 | out: | 1923 | out: |
1887 | if (parent) { | 1924 | if (parent) { |
1888 | n->name_len = n->name ? parent_len(n->name->name) : AUDIT_NAME_FULL; | 1925 | n->name_len = n->name ? parent_len(n->name->name) : AUDIT_NAME_FULL; |