aboutsummaryrefslogtreecommitdiffstats
path: root/kernel
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2014-10-19 19:25:56 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2014-10-19 19:25:56 -0400
commitab074ade9c33b3585da86d62e87bcb3e897a3f54 (patch)
tree142b42182889c64813af997b8701707a3397e834 /kernel
parent61ed53deb1c6a4386d8710dbbfcee8779c381931 (diff)
parent2991dd2b0117e864f394c826af6df144206ce0db (diff)
Merge git://git.infradead.org/users/eparis/audit
Pull audit updates from Eric Paris: "So this change across a whole bunch of arches really solves one basic problem. We want to audit when seccomp is killing a process. seccomp hooks in before the audit syscall entry code. audit_syscall_entry took as an argument the arch of the given syscall. Since the arch is part of what makes a syscall number meaningful it's an important part of the record, but it isn't available when seccomp shoots the syscall... For most arch's we have a better way to get the arch (syscall_get_arch) So the solution was two fold: Implement syscall_get_arch() everywhere there is audit which didn't have it. Use syscall_get_arch() in the seccomp audit code. Having syscall_get_arch() everywhere meant it was a useless flag on the stack and we could get rid of it for the typical syscall entry. The other changes inside the audit system aren't grand, fixed some records that had invalid spaces. Better locking around the task comm field. Removing some dead functions and structs. Make some things static. Really minor stuff" * git://git.infradead.org/users/eparis/audit: (31 commits) audit: rename audit_log_remove_rule to disambiguate for trees audit: cull redundancy in audit_rule_change audit: WARN if audit_rule_change called illegally audit: put rule existence check in canonical order next: openrisc: Fix build audit: get comm using lock to avoid race in string printing audit: remove open_arg() function that is never used audit: correct AUDIT_GET_FEATURE return message type audit: set nlmsg_len for multicast messages. audit: use union for audit_field values since they are mutually exclusive audit: invalid op= values for rules audit: use atomic_t to simplify audit_serial() kernel/audit.c: use ARRAY_SIZE instead of sizeof/sizeof[0] audit: reduce scope of audit_log_fcaps audit: reduce scope of audit_net_id audit: arm64: Remove the audit arch argument to audit_syscall_entry arm64: audit: Add audit hook in syscall_trace_enter/exit() audit: x86: drop arch from __audit_syscall_entry() interface sparc: implement is_32bit_task sparc: properly conditionalize use of TIF_32BIT ...
Diffstat (limited to 'kernel')
-rw-r--r--kernel/audit.c30
-rw-r--r--kernel/audit.h1
-rw-r--r--kernel/audit_tree.c6
-rw-r--r--kernel/audit_watch.c4
-rw-r--r--kernel/auditfilter.c56
-rw-r--r--kernel/auditsc.c28
6 files changed, 56 insertions, 69 deletions
diff --git a/kernel/audit.c b/kernel/audit.c
index ba2ff5a5c600..80983df92cd4 100644
--- a/kernel/audit.c
+++ b/kernel/audit.c
@@ -126,7 +126,7 @@ static atomic_t audit_lost = ATOMIC_INIT(0);
126 126
127/* The netlink socket. */ 127/* The netlink socket. */
128static struct sock *audit_sock; 128static struct sock *audit_sock;
129int audit_net_id; 129static int audit_net_id;
130 130
131/* Hash for inode-based rules */ 131/* Hash for inode-based rules */
132struct list_head audit_inode_hash[AUDIT_INODE_BUCKETS]; 132struct list_head audit_inode_hash[AUDIT_INODE_BUCKETS];
@@ -724,7 +724,7 @@ static int audit_get_feature(struct sk_buff *skb)
724 724
725 seq = nlmsg_hdr(skb)->nlmsg_seq; 725 seq = nlmsg_hdr(skb)->nlmsg_seq;
726 726
727 audit_send_reply(skb, seq, AUDIT_GET, 0, 0, &af, sizeof(af)); 727 audit_send_reply(skb, seq, AUDIT_GET_FEATURE, 0, 0, &af, sizeof(af));
728 728
729 return 0; 729 return 0;
730} 730}
@@ -750,7 +750,7 @@ static int audit_set_feature(struct sk_buff *skb)
750 struct audit_features *uaf; 750 struct audit_features *uaf;
751 int i; 751 int i;
752 752
753 BUILD_BUG_ON(AUDIT_LAST_FEATURE + 1 > sizeof(audit_feature_names)/sizeof(audit_feature_names[0])); 753 BUILD_BUG_ON(AUDIT_LAST_FEATURE + 1 > ARRAY_SIZE(audit_feature_names));
754 uaf = nlmsg_data(nlmsg_hdr(skb)); 754 uaf = nlmsg_data(nlmsg_hdr(skb));
755 755
756 /* if there is ever a version 2 we should handle that here */ 756 /* if there is ever a version 2 we should handle that here */
@@ -1301,19 +1301,9 @@ err:
1301 */ 1301 */
1302unsigned int audit_serial(void) 1302unsigned int audit_serial(void)
1303{ 1303{
1304 static DEFINE_SPINLOCK(serial_lock); 1304 static atomic_t serial = ATOMIC_INIT(0);
1305 static unsigned int serial = 0;
1306 1305
1307 unsigned long flags; 1306 return atomic_add_return(1, &serial);
1308 unsigned int ret;
1309
1310 spin_lock_irqsave(&serial_lock, flags);
1311 do {
1312 ret = ++serial;
1313 } while (unlikely(!ret));
1314 spin_unlock_irqrestore(&serial_lock, flags);
1315
1316 return ret;
1317} 1307}
1318 1308
1319static inline void audit_get_stamp(struct audit_context *ctx, 1309static inline void audit_get_stamp(struct audit_context *ctx,
@@ -1681,7 +1671,7 @@ void audit_log_cap(struct audit_buffer *ab, char *prefix, kernel_cap_t *cap)
1681 } 1671 }
1682} 1672}
1683 1673
1684void audit_log_fcaps(struct audit_buffer *ab, struct audit_names *name) 1674static void audit_log_fcaps(struct audit_buffer *ab, struct audit_names *name)
1685{ 1675{
1686 kernel_cap_t *perm = &name->fcap.permitted; 1676 kernel_cap_t *perm = &name->fcap.permitted;
1687 kernel_cap_t *inh = &name->fcap.inheritable; 1677 kernel_cap_t *inh = &name->fcap.inheritable;
@@ -1860,7 +1850,7 @@ EXPORT_SYMBOL(audit_log_task_context);
1860void audit_log_task_info(struct audit_buffer *ab, struct task_struct *tsk) 1850void audit_log_task_info(struct audit_buffer *ab, struct task_struct *tsk)
1861{ 1851{
1862 const struct cred *cred; 1852 const struct cred *cred;
1863 char name[sizeof(tsk->comm)]; 1853 char comm[sizeof(tsk->comm)];
1864 struct mm_struct *mm = tsk->mm; 1854 struct mm_struct *mm = tsk->mm;
1865 char *tty; 1855 char *tty;
1866 1856
@@ -1894,9 +1884,8 @@ void audit_log_task_info(struct audit_buffer *ab, struct task_struct *tsk)
1894 from_kgid(&init_user_ns, cred->fsgid), 1884 from_kgid(&init_user_ns, cred->fsgid),
1895 tty, audit_get_sessionid(tsk)); 1885 tty, audit_get_sessionid(tsk));
1896 1886
1897 get_task_comm(name, tsk);
1898 audit_log_format(ab, " comm="); 1887 audit_log_format(ab, " comm=");
1899 audit_log_untrustedstring(ab, name); 1888 audit_log_untrustedstring(ab, get_task_comm(comm, tsk));
1900 1889
1901 if (mm) { 1890 if (mm) {
1902 down_read(&mm->mmap_sem); 1891 down_read(&mm->mmap_sem);
@@ -1959,6 +1948,7 @@ void audit_log_end(struct audit_buffer *ab)
1959 } else { 1948 } else {
1960 struct nlmsghdr *nlh = nlmsg_hdr(ab->skb); 1949 struct nlmsghdr *nlh = nlmsg_hdr(ab->skb);
1961 1950
1951 nlh->nlmsg_len = ab->skb->len;
1962 kauditd_send_multicast_skb(ab->skb); 1952 kauditd_send_multicast_skb(ab->skb);
1963 1953
1964 /* 1954 /*
@@ -1970,7 +1960,7 @@ void audit_log_end(struct audit_buffer *ab)
1970 * protocol between the kaudit kernel subsystem and the auditd 1960 * protocol between the kaudit kernel subsystem and the auditd
1971 * userspace code. 1961 * userspace code.
1972 */ 1962 */
1973 nlh->nlmsg_len = ab->skb->len - NLMSG_HDRLEN; 1963 nlh->nlmsg_len -= NLMSG_HDRLEN;
1974 1964
1975 if (audit_pid) { 1965 if (audit_pid) {
1976 skb_queue_tail(&audit_skb_queue, ab->skb); 1966 skb_queue_tail(&audit_skb_queue, ab->skb);
diff --git a/kernel/audit.h b/kernel/audit.h
index 7bb65730c890..3cdffad5a1d9 100644
--- a/kernel/audit.h
+++ b/kernel/audit.h
@@ -222,7 +222,6 @@ extern void audit_copy_inode(struct audit_names *name,
222 const struct inode *inode); 222 const struct inode *inode);
223extern void audit_log_cap(struct audit_buffer *ab, char *prefix, 223extern void audit_log_cap(struct audit_buffer *ab, char *prefix,
224 kernel_cap_t *cap); 224 kernel_cap_t *cap);
225extern void audit_log_fcaps(struct audit_buffer *ab, struct audit_names *name);
226extern void audit_log_name(struct audit_context *context, 225extern void audit_log_name(struct audit_context *context,
227 struct audit_names *n, struct path *path, 226 struct audit_names *n, struct path *path,
228 int record_num, int *call_panic); 227 int record_num, int *call_panic);
diff --git a/kernel/audit_tree.c b/kernel/audit_tree.c
index 135944a7b28a..e242e3a9864a 100644
--- a/kernel/audit_tree.c
+++ b/kernel/audit_tree.c
@@ -449,7 +449,7 @@ static int tag_chunk(struct inode *inode, struct audit_tree *tree)
449 return 0; 449 return 0;
450} 450}
451 451
452static void audit_log_remove_rule(struct audit_krule *rule) 452static void audit_tree_log_remove_rule(struct audit_krule *rule)
453{ 453{
454 struct audit_buffer *ab; 454 struct audit_buffer *ab;
455 455
@@ -457,7 +457,7 @@ static void audit_log_remove_rule(struct audit_krule *rule)
457 if (unlikely(!ab)) 457 if (unlikely(!ab))
458 return; 458 return;
459 audit_log_format(ab, "op="); 459 audit_log_format(ab, "op=");
460 audit_log_string(ab, "remove rule"); 460 audit_log_string(ab, "remove_rule");
461 audit_log_format(ab, " dir="); 461 audit_log_format(ab, " dir=");
462 audit_log_untrustedstring(ab, rule->tree->pathname); 462 audit_log_untrustedstring(ab, rule->tree->pathname);
463 audit_log_key(ab, rule->filterkey); 463 audit_log_key(ab, rule->filterkey);
@@ -476,7 +476,7 @@ static void kill_rules(struct audit_tree *tree)
476 list_del_init(&rule->rlist); 476 list_del_init(&rule->rlist);
477 if (rule->tree) { 477 if (rule->tree) {
478 /* not a half-baked one */ 478 /* not a half-baked one */
479 audit_log_remove_rule(rule); 479 audit_tree_log_remove_rule(rule);
480 rule->tree = NULL; 480 rule->tree = NULL;
481 list_del_rcu(&entry->list); 481 list_del_rcu(&entry->list);
482 list_del(&entry->rule.list); 482 list_del(&entry->rule.list);
diff --git a/kernel/audit_watch.c b/kernel/audit_watch.c
index 70b4554d2fbe..ad9c1682f616 100644
--- a/kernel/audit_watch.c
+++ b/kernel/audit_watch.c
@@ -314,7 +314,7 @@ static void audit_update_watch(struct audit_parent *parent,
314 &nentry->rule.list); 314 &nentry->rule.list);
315 } 315 }
316 316
317 audit_watch_log_rule_change(r, owatch, "updated rules"); 317 audit_watch_log_rule_change(r, owatch, "updated_rules");
318 318
319 call_rcu(&oentry->rcu, audit_free_rule_rcu); 319 call_rcu(&oentry->rcu, audit_free_rule_rcu);
320 } 320 }
@@ -342,7 +342,7 @@ static void audit_remove_parent_watches(struct audit_parent *parent)
342 list_for_each_entry_safe(w, nextw, &parent->watches, wlist) { 342 list_for_each_entry_safe(w, nextw, &parent->watches, wlist) {
343 list_for_each_entry_safe(r, nextr, &w->rules, rlist) { 343 list_for_each_entry_safe(r, nextr, &w->rules, rlist) {
344 e = container_of(r, struct audit_entry, rule); 344 e = container_of(r, struct audit_entry, rule);
345 audit_watch_log_rule_change(r, w, "remove rule"); 345 audit_watch_log_rule_change(r, w, "remove_rule");
346 list_del(&r->rlist); 346 list_del(&r->rlist);
347 list_del(&r->list); 347 list_del(&r->list);
348 list_del_rcu(&e->list); 348 list_del_rcu(&e->list);
diff --git a/kernel/auditfilter.c b/kernel/auditfilter.c
index c447cd9848d1..3598e13f2a65 100644
--- a/kernel/auditfilter.c
+++ b/kernel/auditfilter.c
@@ -71,6 +71,24 @@ static struct list_head audit_rules_list[AUDIT_NR_FILTERS] = {
71 71
72DEFINE_MUTEX(audit_filter_mutex); 72DEFINE_MUTEX(audit_filter_mutex);
73 73
74static void audit_free_lsm_field(struct audit_field *f)
75{
76 switch (f->type) {
77 case AUDIT_SUBJ_USER:
78 case AUDIT_SUBJ_ROLE:
79 case AUDIT_SUBJ_TYPE:
80 case AUDIT_SUBJ_SEN:
81 case AUDIT_SUBJ_CLR:
82 case AUDIT_OBJ_USER:
83 case AUDIT_OBJ_ROLE:
84 case AUDIT_OBJ_TYPE:
85 case AUDIT_OBJ_LEV_LOW:
86 case AUDIT_OBJ_LEV_HIGH:
87 kfree(f->lsm_str);
88 security_audit_rule_free(f->lsm_rule);
89 }
90}
91
74static inline void audit_free_rule(struct audit_entry *e) 92static inline void audit_free_rule(struct audit_entry *e)
75{ 93{
76 int i; 94 int i;
@@ -80,11 +98,8 @@ static inline void audit_free_rule(struct audit_entry *e)
80 if (erule->watch) 98 if (erule->watch)
81 audit_put_watch(erule->watch); 99 audit_put_watch(erule->watch);
82 if (erule->fields) 100 if (erule->fields)
83 for (i = 0; i < erule->field_count; i++) { 101 for (i = 0; i < erule->field_count; i++)
84 struct audit_field *f = &erule->fields[i]; 102 audit_free_lsm_field(&erule->fields[i]);
85 kfree(f->lsm_str);
86 security_audit_rule_free(f->lsm_rule);
87 }
88 kfree(erule->fields); 103 kfree(erule->fields);
89 kfree(erule->filterkey); 104 kfree(erule->filterkey);
90 kfree(e); 105 kfree(e);
@@ -148,7 +163,7 @@ static inline int audit_to_inode(struct audit_krule *krule,
148 struct audit_field *f) 163 struct audit_field *f)
149{ 164{
150 if (krule->listnr != AUDIT_FILTER_EXIT || 165 if (krule->listnr != AUDIT_FILTER_EXIT ||
151 krule->watch || krule->inode_f || krule->tree || 166 krule->inode_f || krule->watch || krule->tree ||
152 (f->op != Audit_equal && f->op != Audit_not_equal)) 167 (f->op != Audit_equal && f->op != Audit_not_equal))
153 return -EINVAL; 168 return -EINVAL;
154 169
@@ -422,10 +437,6 @@ static struct audit_entry *audit_data_to_entry(struct audit_rule_data *data,
422 437
423 f->type = data->fields[i]; 438 f->type = data->fields[i];
424 f->val = data->values[i]; 439 f->val = data->values[i];
425 f->uid = INVALID_UID;
426 f->gid = INVALID_GID;
427 f->lsm_str = NULL;
428 f->lsm_rule = NULL;
429 440
430 /* Support legacy tests for a valid loginuid */ 441 /* Support legacy tests for a valid loginuid */
431 if ((f->type == AUDIT_LOGINUID) && (f->val == AUDIT_UID_UNSET)) { 442 if ((f->type == AUDIT_LOGINUID) && (f->val == AUDIT_UID_UNSET)) {
@@ -1053,30 +1064,27 @@ int audit_rule_change(int type, __u32 portid, int seq, void *data,
1053 int err = 0; 1064 int err = 0;
1054 struct audit_entry *entry; 1065 struct audit_entry *entry;
1055 1066
1067 entry = audit_data_to_entry(data, datasz);
1068 if (IS_ERR(entry))
1069 return PTR_ERR(entry);
1070
1056 switch (type) { 1071 switch (type) {
1057 case AUDIT_ADD_RULE: 1072 case AUDIT_ADD_RULE:
1058 entry = audit_data_to_entry(data, datasz);
1059 if (IS_ERR(entry))
1060 return PTR_ERR(entry);
1061
1062 err = audit_add_rule(entry); 1073 err = audit_add_rule(entry);
1063 audit_log_rule_change("add rule", &entry->rule, !err); 1074 audit_log_rule_change("add_rule", &entry->rule, !err);
1064 if (err)
1065 audit_free_rule(entry);
1066 break; 1075 break;
1067 case AUDIT_DEL_RULE: 1076 case AUDIT_DEL_RULE:
1068 entry = audit_data_to_entry(data, datasz);
1069 if (IS_ERR(entry))
1070 return PTR_ERR(entry);
1071
1072 err = audit_del_rule(entry); 1077 err = audit_del_rule(entry);
1073 audit_log_rule_change("remove rule", &entry->rule, !err); 1078 audit_log_rule_change("remove_rule", &entry->rule, !err);
1074 audit_free_rule(entry);
1075 break; 1079 break;
1076 default: 1080 default:
1077 return -EINVAL; 1081 err = -EINVAL;
1082 WARN_ON(1);
1078 } 1083 }
1079 1084
1085 if (err || type == AUDIT_DEL_RULE)
1086 audit_free_rule(entry);
1087
1080 return err; 1088 return err;
1081} 1089}
1082 1090
diff --git a/kernel/auditsc.c b/kernel/auditsc.c
index 7208c1df248d..e420a0c41b5f 100644
--- a/kernel/auditsc.c
+++ b/kernel/auditsc.c
@@ -67,6 +67,7 @@
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>
@@ -125,14 +126,6 @@ struct audit_tree_refs {
125 struct audit_chunk *c[31]; 126 struct audit_chunk *c[31];
126}; 127};
127 128
128static 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
136static int audit_match_perm(struct audit_context *ctx, int mask) 129static int audit_match_perm(struct audit_context *ctx, int mask)
137{ 130{
138 unsigned n; 131 unsigned n;
@@ -1505,7 +1498,6 @@ void __audit_free(struct task_struct *tsk)
1505 1498
1506/** 1499/**
1507 * audit_syscall_entry - fill in an audit record at syscall entry 1500 * audit_syscall_entry - fill in an audit record at syscall entry
1508 * @arch: architecture type
1509 * @major: major syscall type (function) 1501 * @major: major syscall type (function)
1510 * @a1: additional syscall register 1 1502 * @a1: additional syscall register 1
1511 * @a2: additional syscall register 2 1503 * @a2: additional syscall register 2
@@ -1520,9 +1512,8 @@ void __audit_free(struct task_struct *tsk)
1520 * will only be written if another part of the kernel requests that it 1512 * will only be written if another part of the kernel requests that it
1521 * be written). 1513 * be written).
1522 */ 1514 */
1523void __audit_syscall_entry(int arch, int major, 1515void __audit_syscall_entry(int major, unsigned long a1, unsigned long a2,
1524 unsigned long a1, unsigned long a2, 1516 unsigned long a3, unsigned long a4)
1525 unsigned long a3, unsigned long a4)
1526{ 1517{
1527 struct task_struct *tsk = current; 1518 struct task_struct *tsk = current;
1528 struct audit_context *context = tsk->audit_context; 1519 struct audit_context *context = tsk->audit_context;
@@ -1536,7 +1527,7 @@ void __audit_syscall_entry(int arch, int major,
1536 if (!audit_enabled) 1527 if (!audit_enabled)
1537 return; 1528 return;
1538 1529
1539 context->arch = arch; 1530 context->arch = syscall_get_arch();
1540 context->major = major; 1531 context->major = major;
1541 context->argv[0] = a1; 1532 context->argv[0] = a1;
1542 context->argv[1] = a2; 1533 context->argv[1] = a2;
@@ -2433,6 +2424,7 @@ static void audit_log_task(struct audit_buffer *ab)
2433 kgid_t gid; 2424 kgid_t gid;
2434 unsigned int sessionid; 2425 unsigned int sessionid;
2435 struct mm_struct *mm = current->mm; 2426 struct mm_struct *mm = current->mm;
2427 char comm[sizeof(current->comm)];
2436 2428
2437 auid = audit_get_loginuid(current); 2429 auid = audit_get_loginuid(current);
2438 sessionid = audit_get_sessionid(current); 2430 sessionid = audit_get_sessionid(current);
@@ -2445,7 +2437,7 @@ static void audit_log_task(struct audit_buffer *ab)
2445 sessionid); 2437 sessionid);
2446 audit_log_task_context(ab); 2438 audit_log_task_context(ab);
2447 audit_log_format(ab, " pid=%d comm=", task_pid_nr(current)); 2439 audit_log_format(ab, " pid=%d comm=", task_pid_nr(current));
2448 audit_log_untrustedstring(ab, current->comm); 2440 audit_log_untrustedstring(ab, get_task_comm(comm, current));
2449 if (mm) { 2441 if (mm) {
2450 down_read(&mm->mmap_sem); 2442 down_read(&mm->mmap_sem);
2451 if (mm->exe_file) 2443 if (mm->exe_file)
@@ -2488,11 +2480,9 @@ void __audit_seccomp(unsigned long syscall, long signr, int code)
2488 if (unlikely(!ab)) 2480 if (unlikely(!ab))
2489 return; 2481 return;
2490 audit_log_task(ab); 2482 audit_log_task(ab);
2491 audit_log_format(ab, " sig=%ld", signr); 2483 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); 2484 signr, syscall_get_arch(), syscall, is_compat_task(),
2493 audit_log_format(ab, " compat=%d", is_compat_task()); 2485 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); 2486 audit_log_end(ab);
2497} 2487}
2498 2488