diff options
| author | Dmitry Torokhov <dmitry.torokhov@gmail.com> | 2015-02-10 14:35:36 -0500 |
|---|---|---|
| committer | Dmitry Torokhov <dmitry.torokhov@gmail.com> | 2015-02-10 14:35:36 -0500 |
| commit | 4ba24fef3eb3b142197135223b90ced2f319cd53 (patch) | |
| tree | a20c125b27740ec7b4c761b11d801108e1b316b2 /kernel/auditsc.c | |
| parent | 47c1ffb2b6b630894e9a16442611c056ab21c057 (diff) | |
| parent | 98a4a59ee31a12105a2b84f5b8b515ac2cb208ef (diff) | |
Merge branch 'next' into for-linus
Prepare first round of input updates for 3.20.
Diffstat (limited to 'kernel/auditsc.c')
| -rw-r--r-- | kernel/auditsc.c | 86 |
1 files changed, 59 insertions, 27 deletions
diff --git a/kernel/auditsc.c b/kernel/auditsc.c index 21eae3c05ec0..072566dd0caf 100644 --- a/kernel/auditsc.c +++ b/kernel/auditsc.c | |||
| @@ -67,10 +67,13 @@ | |||
| 67 | #include <linux/binfmts.h> | 67 | #include <linux/binfmts.h> |
| 68 | #include <linux/highmem.h> | 68 | #include <linux/highmem.h> |
| 69 | #include <linux/syscalls.h> | 69 | #include <linux/syscalls.h> |
| 70 | #include <asm/syscall.h> | ||
| 70 | #include <linux/capability.h> | 71 | #include <linux/capability.h> |
| 71 | #include <linux/fs_struct.h> | 72 | #include <linux/fs_struct.h> |
| 72 | #include <linux/compat.h> | 73 | #include <linux/compat.h> |
| 73 | #include <linux/ctype.h> | 74 | #include <linux/ctype.h> |
| 75 | #include <linux/string.h> | ||
| 76 | #include <uapi/linux/limits.h> | ||
| 74 | 77 | ||
| 75 | #include "audit.h" | 78 | #include "audit.h" |
| 76 | 79 | ||
| @@ -125,14 +128,6 @@ struct audit_tree_refs { | |||
| 125 | struct audit_chunk *c[31]; | 128 | struct audit_chunk *c[31]; |
| 126 | }; | 129 | }; |
| 127 | 130 | ||
| 128 | static inline int open_arg(int flags, int mask) | ||
| 129 | { | ||
| 130 | int n = ACC_MODE(flags); | ||
| 131 | if (flags & (O_TRUNC | O_CREAT)) | ||
| 132 | n |= AUDIT_PERM_WRITE; | ||
| 133 | return n & mask; | ||
| 134 | } | ||
| 135 | |||
| 136 | static int audit_match_perm(struct audit_context *ctx, int mask) | 131 | static int audit_match_perm(struct audit_context *ctx, int mask) |
| 137 | { | 132 | { |
| 138 | unsigned n; | 133 | unsigned n; |
| @@ -1505,7 +1500,6 @@ void __audit_free(struct task_struct *tsk) | |||
| 1505 | 1500 | ||
| 1506 | /** | 1501 | /** |
| 1507 | * audit_syscall_entry - fill in an audit record at syscall entry | 1502 | * audit_syscall_entry - fill in an audit record at syscall entry |
| 1508 | * @arch: architecture type | ||
| 1509 | * @major: major syscall type (function) | 1503 | * @major: major syscall type (function) |
| 1510 | * @a1: additional syscall register 1 | 1504 | * @a1: additional syscall register 1 |
| 1511 | * @a2: additional syscall register 2 | 1505 | * @a2: additional syscall register 2 |
| @@ -1520,9 +1514,8 @@ void __audit_free(struct task_struct *tsk) | |||
| 1520 | * will only be written if another part of the kernel requests that it | 1514 | * will only be written if another part of the kernel requests that it |
| 1521 | * be written). | 1515 | * be written). |
| 1522 | */ | 1516 | */ |
| 1523 | void __audit_syscall_entry(int arch, int major, | 1517 | void __audit_syscall_entry(int major, unsigned long a1, unsigned long a2, |
| 1524 | unsigned long a1, unsigned long a2, | 1518 | unsigned long a3, unsigned long a4) |
| 1525 | unsigned long a3, unsigned long a4) | ||
| 1526 | { | 1519 | { |
| 1527 | struct task_struct *tsk = current; | 1520 | struct task_struct *tsk = current; |
| 1528 | struct audit_context *context = tsk->audit_context; | 1521 | struct audit_context *context = tsk->audit_context; |
| @@ -1536,7 +1529,7 @@ void __audit_syscall_entry(int arch, int major, | |||
| 1536 | if (!audit_enabled) | 1529 | if (!audit_enabled) |
| 1537 | return; | 1530 | return; |
| 1538 | 1531 | ||
| 1539 | context->arch = arch; | 1532 | context->arch = syscall_get_arch(); |
| 1540 | context->major = major; | 1533 | context->major = major; |
| 1541 | context->argv[0] = a1; | 1534 | context->argv[0] = a1; |
| 1542 | context->argv[1] = a2; | 1535 | context->argv[1] = a2; |
| @@ -1870,8 +1863,7 @@ void __audit_inode(struct filename *name, const struct dentry *dentry, | |||
| 1870 | } | 1863 | } |
| 1871 | 1864 | ||
| 1872 | list_for_each_entry_reverse(n, &context->names_list, list) { | 1865 | list_for_each_entry_reverse(n, &context->names_list, list) { |
| 1873 | /* does the name pointer match? */ | 1866 | if (!n->name || strcmp(n->name->name, name->name)) |
| 1874 | if (!n->name || n->name->name != name->name) | ||
| 1875 | continue; | 1867 | continue; |
| 1876 | 1868 | ||
| 1877 | /* match the correct record type */ | 1869 | /* match the correct record type */ |
| @@ -1886,12 +1878,48 @@ void __audit_inode(struct filename *name, const struct dentry *dentry, | |||
| 1886 | } | 1878 | } |
| 1887 | 1879 | ||
| 1888 | out_alloc: | 1880 | out_alloc: |
| 1889 | /* 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 */ |
| 1890 | * anonymous entry. | 1882 | n = audit_alloc_name(context, AUDIT_TYPE_UNKNOWN); |
| 1891 | */ | ||
| 1892 | n = audit_alloc_name(context, AUDIT_TYPE_NORMAL); | ||
| 1893 | if (!n) | 1883 | if (!n) |
| 1894 | 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 | } | ||
| 1895 | out: | 1923 | out: |
| 1896 | if (parent) { | 1924 | if (parent) { |
| 1897 | 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; |
| @@ -1906,6 +1934,11 @@ out: | |||
| 1906 | audit_copy_inode(n, dentry, inode); | 1934 | audit_copy_inode(n, dentry, inode); |
| 1907 | } | 1935 | } |
| 1908 | 1936 | ||
| 1937 | void __audit_file(const struct file *file) | ||
| 1938 | { | ||
| 1939 | __audit_inode(NULL, file->f_path.dentry, 0); | ||
| 1940 | } | ||
| 1941 | |||
| 1909 | /** | 1942 | /** |
| 1910 | * __audit_inode_child - collect inode info for created/removed objects | 1943 | * __audit_inode_child - collect inode info for created/removed objects |
| 1911 | * @parent: inode of dentry parent | 1944 | * @parent: inode of dentry parent |
| @@ -2382,7 +2415,7 @@ int __audit_log_bprm_fcaps(struct linux_binprm *bprm, | |||
| 2382 | ax->d.next = context->aux; | 2415 | ax->d.next = context->aux; |
| 2383 | context->aux = (void *)ax; | 2416 | context->aux = (void *)ax; |
| 2384 | 2417 | ||
| 2385 | dentry = dget(bprm->file->f_dentry); | 2418 | dentry = dget(bprm->file->f_path.dentry); |
| 2386 | get_vfs_caps_from_disk(dentry, &vcaps); | 2419 | get_vfs_caps_from_disk(dentry, &vcaps); |
| 2387 | dput(dentry); | 2420 | dput(dentry); |
| 2388 | 2421 | ||
| @@ -2406,7 +2439,7 @@ int __audit_log_bprm_fcaps(struct linux_binprm *bprm, | |||
| 2406 | * @new: the new credentials | 2439 | * @new: the new credentials |
| 2407 | * @old: the old (current) credentials | 2440 | * @old: the old (current) credentials |
| 2408 | * | 2441 | * |
| 2409 | * Record the aguments userspace sent to sys_capset for later printing by the | 2442 | * Record the arguments userspace sent to sys_capset for later printing by the |
| 2410 | * audit system if applicable | 2443 | * audit system if applicable |
| 2411 | */ | 2444 | */ |
| 2412 | void __audit_log_capset(const struct cred *new, const struct cred *old) | 2445 | void __audit_log_capset(const struct cred *new, const struct cred *old) |
| @@ -2433,6 +2466,7 @@ static void audit_log_task(struct audit_buffer *ab) | |||
| 2433 | kgid_t gid; | 2466 | kgid_t gid; |
| 2434 | unsigned int sessionid; | 2467 | unsigned int sessionid; |
| 2435 | struct mm_struct *mm = current->mm; | 2468 | struct mm_struct *mm = current->mm; |
| 2469 | char comm[sizeof(current->comm)]; | ||
| 2436 | 2470 | ||
| 2437 | auid = audit_get_loginuid(current); | 2471 | auid = audit_get_loginuid(current); |
| 2438 | sessionid = audit_get_sessionid(current); | 2472 | sessionid = audit_get_sessionid(current); |
| @@ -2445,7 +2479,7 @@ static void audit_log_task(struct audit_buffer *ab) | |||
| 2445 | sessionid); | 2479 | sessionid); |
| 2446 | audit_log_task_context(ab); | 2480 | audit_log_task_context(ab); |
| 2447 | audit_log_format(ab, " pid=%d comm=", task_pid_nr(current)); | 2481 | audit_log_format(ab, " pid=%d comm=", task_pid_nr(current)); |
| 2448 | audit_log_untrustedstring(ab, current->comm); | 2482 | audit_log_untrustedstring(ab, get_task_comm(comm, current)); |
| 2449 | if (mm) { | 2483 | if (mm) { |
| 2450 | down_read(&mm->mmap_sem); | 2484 | down_read(&mm->mmap_sem); |
| 2451 | if (mm->exe_file) | 2485 | if (mm->exe_file) |
| @@ -2488,11 +2522,9 @@ void __audit_seccomp(unsigned long syscall, long signr, int code) | |||
| 2488 | if (unlikely(!ab)) | 2522 | if (unlikely(!ab)) |
| 2489 | return; | 2523 | return; |
| 2490 | audit_log_task(ab); | 2524 | audit_log_task(ab); |
| 2491 | audit_log_format(ab, " sig=%ld", signr); | 2525 | audit_log_format(ab, " sig=%ld arch=%x syscall=%ld compat=%d ip=0x%lx code=0x%x", |
| 2492 | audit_log_format(ab, " syscall=%ld", syscall); | 2526 | signr, syscall_get_arch(), syscall, is_compat_task(), |
| 2493 | audit_log_format(ab, " compat=%d", is_compat_task()); | 2527 | KSTK_EIP(current), code); |
| 2494 | audit_log_format(ab, " ip=0x%lx", KSTK_EIP(current)); | ||
| 2495 | audit_log_format(ab, " code=0x%x", code); | ||
| 2496 | audit_log_end(ab); | 2528 | audit_log_end(ab); |
| 2497 | } | 2529 | } |
| 2498 | 2530 | ||
