Commit 5e0f872c7d7e371fbdf09e864eddd24bddfda8fe

Authored by Linus Torvalds

Merge branch 'upstream' of git://git.infradead.org/users/pcmoore/audit

Pull audit fix from Paul Moore:
 "One audit patch to resolve a panic/oops when recording filenames in
  the audit log, see the mail archive link below.

  The fix isn't as nice as I would like, as it involves an allocate/copy
  of the filename, but it solves the problem and the overhead should
  only affect users who have configured audit rules involving file
  names.

  We'll revisit this issue with future kernels in an attempt to make
  this suck less, but in the meantime I think this fix should go into
  the next release of v3.19-rcX.

  [ https://marc.info/?t=141986927600001&r=1&w=2 ]"

* 'upstream' of git://git.infradead.org/users/pcmoore/audit:
  audit: create private file name copies when auditing inodes

Showing 1 changed file Side-by-side Diff

... ... @@ -72,6 +72,8 @@
72 72 #include <linux/fs_struct.h>
73 73 #include <linux/compat.h>
74 74 #include <linux/ctype.h>
  75 +#include <linux/string.h>
  76 +#include <uapi/linux/limits.h>
75 77  
76 78 #include "audit.h"
77 79  
... ... @@ -1861,8 +1863,7 @@
1861 1863 }
1862 1864  
1863 1865 list_for_each_entry_reverse(n, &context->names_list, list) {
1864   - /* does the name pointer match? */
1865   - if (!n->name || n->name->name != name->name)
  1866 + if (!n->name || strcmp(n->name->name, name->name))
1866 1867 continue;
1867 1868  
1868 1869 /* match the correct record type */
1869 1870  
... ... @@ -1881,14 +1882,44 @@
1881 1882 n = audit_alloc_name(context, AUDIT_TYPE_UNKNOWN);
1882 1883 if (!n)
1883 1884 return;
1884   - if (name)
1885   - /* since name is not NULL we know there is already a matching
1886   - * name record, see audit_getname(), so there must be a type
1887   - * mismatch; reuse the string path since the original name
1888   - * record will keep the string valid until we free it in
1889   - * audit_free_names() */
1890   - n->name = name;
  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();
1891 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 + }
1892 1923 out:
1893 1924 if (parent) {
1894 1925 n->name_len = n->name ? parent_len(n->name->name) : AUDIT_NAME_FULL;