diff options
Diffstat (limited to 'kernel/auditfilter.c')
-rw-r--r-- | kernel/auditfilter.c | 37 |
1 files changed, 32 insertions, 5 deletions
diff --git a/kernel/auditfilter.c b/kernel/auditfilter.c index 6a9a5c5a4e7..a44879b0c72 100644 --- a/kernel/auditfilter.c +++ b/kernel/auditfilter.c @@ -302,6 +302,15 @@ int __init audit_register_class(int class, unsigned *list) return 0; } +int audit_match_class(int class, unsigned syscall) +{ + if (unlikely(syscall >= AUDIT_BITMASK_SIZE * sizeof(__u32))) + return 0; + if (unlikely(class >= AUDIT_SYSCALL_CLASSES || !classes[class])) + return 0; + return classes[class][AUDIT_WORD(syscall)] & AUDIT_BIT(syscall); +} + /* Common user-space to kernel rule translation. */ static inline struct audit_entry *audit_to_entry_common(struct audit_rule *rule) { @@ -404,6 +413,7 @@ static struct audit_entry *audit_rule_to_entry(struct audit_rule *rule) case AUDIT_PERS: case AUDIT_ARCH: case AUDIT_MSGTYPE: + case AUDIT_PPID: case AUDIT_DEVMAJOR: case AUDIT_DEVMINOR: case AUDIT_EXIT: @@ -413,6 +423,10 @@ static struct audit_entry *audit_rule_to_entry(struct audit_rule *rule) case AUDIT_ARG2: case AUDIT_ARG3: break; + case AUDIT_PERM: + if (f->val & ~15) + goto exit_free; + break; case AUDIT_INODE: err = audit_to_inode(&entry->rule, f); if (err) @@ -567,6 +581,10 @@ static struct audit_entry *audit_data_to_entry(struct audit_rule_data *data, entry->rule.buflen += f->val; entry->rule.filterkey = str; break; + case AUDIT_PERM: + if (f->val & ~15) + goto exit_free; + break; default: goto exit_free; } @@ -913,7 +931,7 @@ static void audit_update_watch(struct audit_parent *parent, } ab = audit_log_start(NULL, GFP_KERNEL, AUDIT_CONFIG_CHANGE); - audit_log_format(ab, "audit updated rules specifying watch="); + audit_log_format(ab, "audit updated rules specifying path="); audit_log_untrustedstring(ab, owatch->path); audit_log_format(ab, " with dev=%u ino=%lu\n", dev, ino); audit_log_end(ab); @@ -936,19 +954,28 @@ static void audit_remove_parent_watches(struct audit_parent *parent) struct audit_watch *w, *nextw; struct audit_krule *r, *nextr; struct audit_entry *e; + struct audit_buffer *ab; mutex_lock(&audit_filter_mutex); parent->flags |= AUDIT_PARENT_INVALID; list_for_each_entry_safe(w, nextw, &parent->watches, wlist) { list_for_each_entry_safe(r, nextr, &w->rules, rlist) { e = container_of(r, struct audit_entry, rule); + + ab = audit_log_start(NULL, GFP_KERNEL, AUDIT_CONFIG_CHANGE); + audit_log_format(ab, "audit implicitly removed rule path="); + audit_log_untrustedstring(ab, w->path); + if (r->filterkey) { + audit_log_format(ab, " key="); + audit_log_untrustedstring(ab, r->filterkey); + } else + audit_log_format(ab, " key=(null)"); + audit_log_format(ab, " list=%d", r->listnr); + audit_log_end(ab); + list_del(&r->rlist); list_del_rcu(&e->list); call_rcu(&e->rcu, audit_free_rule_rcu); - - audit_log(NULL, GFP_KERNEL, AUDIT_CONFIG_CHANGE, - "audit implicitly removed rule from list=%d\n", - AUDIT_FILTER_EXIT); } audit_remove_watch(w); } |