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(a)redhat.com>
---
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