Skip to content

Commit 5e0f872

Browse files
committed
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
2 parents 7f40548 + fcf22d8 commit 5e0f872

File tree

1 file changed

+40
-9
lines changed

1 file changed

+40
-9
lines changed

kernel/auditsc.c

Lines changed: 40 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -72,6 +72,8 @@
7272
#include <linux/fs_struct.h>
7373
#include <linux/compat.h>
7474
#include <linux/ctype.h>
75+
#include <linux/string.h>
76+
#include <uapi/linux/limits.h>
7577

7678
#include "audit.h"
7779

@@ -1861,8 +1863,7 @@ void __audit_inode(struct filename *name, const struct dentry *dentry,
18611863
}
18621864

18631865
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))
18661867
continue;
18671868

18681869
/* match the correct record type */
@@ -1881,14 +1882,44 @@ void __audit_inode(struct filename *name, const struct dentry *dentry,
18811882
n = audit_alloc_name(context, AUDIT_TYPE_UNKNOWN);
18821883
if (!n)
18831884
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();
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;
18911903

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+
}
18921923
out:
18931924
if (parent) {
18941925
n->name_len = n->name ? parent_len(n->name->name) : AUDIT_NAME_FULL;

0 commit comments

Comments
 (0)