|
@@ -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);
|
|
|
}
|