[PATCH] audit: process errors from filter user rules

From: Richard Guy Briggs
Date: Wed Dec 04 2013 - 22:45:44 EST


Errors from filter user rules were previously ignored, and worse, an error on
a AUDIT_NEVER rule disabled logging on that rule. On -ESTALE, retry up to 5
times. On error on AUDIT_NEVER rules, log.

Signed-off-by: Richard Guy Briggs <rgb@xxxxxxxxxx>
---
kernel/audit.c | 2 +-
kernel/auditfilter.c | 44 +++++++++++++++++++++++++++++++-------------
2 files changed, 32 insertions(+), 14 deletions(-)

diff --git a/kernel/audit.c b/kernel/audit.c
index 4cbc945..c93cf06 100644
--- a/kernel/audit.c
+++ b/kernel/audit.c
@@ -706,7 +706,7 @@ static int audit_receive_msg(struct sk_buff *skb, struct nlmsghdr *nlh)
return 0;

err = audit_filter_user(msg_type);
- if (err == 1) {
+ if (err) { /* match or error */
err = 0;
if (msg_type == AUDIT_USER_TTY) {
err = tty_audit_push_current();
diff --git a/kernel/auditfilter.c b/kernel/auditfilter.c
index b4c6e03..1a7dfa5 100644
--- a/kernel/auditfilter.c
+++ b/kernel/auditfilter.c
@@ -1272,8 +1272,8 @@ static int audit_filter_user_rules(struct audit_krule *rule, int type,
break;
}

- if (!result)
- return 0;
+ if (result <= 0)
+ return result;
}
switch (rule->action) {
case AUDIT_NEVER: *state = AUDIT_DISABLED; break;
@@ -1286,19 +1286,37 @@ int audit_filter_user(int type)
{
enum audit_state state = AUDIT_DISABLED;
struct audit_entry *e;
- int ret = 1;
-
- rcu_read_lock();
- list_for_each_entry_rcu(e, &audit_filter_list[AUDIT_FILTER_USER], list) {
- if (audit_filter_user_rules(&e->rule, type, &state)) {
- if (state == AUDIT_DISABLED)
- ret = 0;
- break;
+ int rc, count = 0, retry = 0, ret = 1; /* Audit by default */
+#define FILTER_RETRY_LIMIT 5
+
+ do {
+ rcu_read_lock();
+ list_for_each_entry_rcu(e,
+ &audit_filter_list[AUDIT_FILTER_USER],
+ list) {
+ retry = 0;
+ rc = audit_filter_user_rules(&e->rule, type, &state);
+ if (rc > 0) {
+ if (state == AUDIT_DISABLED)
+ ret = 0;
+ break;
+ } else if (rc < 0) {
+ if (rc == -ESTALE && count < FILTER_RETRY_LIMIT) {
+ rcu_read_unlock();
+ count++;
+ retry = 1;
+ cond_resched();
+ } else {
+ ret = rc;
+ }
+ break;
+ }
}
- }
- rcu_read_unlock();
+ if (!retry)
+ rcu_read_unlock();
+ } while (retry);

- return ret; /* Audit by default */
+ return ret;
}

int audit_filter_type(int type)
--
1.7.1

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/