diff options
author | Dustin Kirkland <dustin.kirkland@us.ibm.com> | 2005-11-03 16:12:36 (GMT) |
---|---|---|
committer | Al Viro <viro@zeniv.linux.org.uk> | 2006-03-20 19:08:54 (GMT) |
commit | c8edc80c8b8c397c53f4f659a05b9ea6208029bf (patch) | |
tree | 0b09c0ff9ea28038b711d7368100302a1cc69b6d /kernel | |
parent | 73241ccca0f7786933f1d31b3d86f2456549953a (diff) | |
download | linux-fsl-qoriq-c8edc80c8b8c397c53f4f659a05b9ea6208029bf.tar.xz |
[PATCH] Exclude messages by message type
- Add a new, 5th filter called "exclude".
- And add a new field AUDIT_MSGTYPE.
- Define a new function audit_filter_exclude() that takes a message type
as input and examines all rules in the filter. It returns '1' if the
message is to be excluded, and '0' otherwise.
- Call the audit_filter_exclude() function near the top of
audit_log_start() just after asserting audit_initialized. If the
message type is not to be audited, return NULL very early, before
doing a lot of work.
[combined with followup fix for bug in original patch, Nov 4, same author]
[combined with later renaming AUDIT_FILTER_EXCLUDE->AUDIT_FILTER_TYPE
and audit_filter_exclude() -> audit_filter_type()]
Signed-off-by: Dustin Kirkland <dustin.kirkland@us.ibm.com>
Signed-off-by: David Woodhouse <dwmw2@infradead.org>
Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
Diffstat (limited to 'kernel')
-rw-r--r-- | kernel/audit.c | 3 | ||||
-rw-r--r-- | kernel/auditsc.c | 35 |
2 files changed, 37 insertions, 1 deletions
diff --git a/kernel/audit.c b/kernel/audit.c index 6d61dd7..1c3eb1b 100644 --- a/kernel/audit.c +++ b/kernel/audit.c @@ -702,6 +702,9 @@ struct audit_buffer *audit_log_start(struct audit_context *ctx, gfp_t gfp_mask, if (!audit_initialized) return NULL; + if (unlikely(audit_filter_type(type))) + return NULL; + if (gfp_mask & __GFP_WAIT) reserve = 0; else diff --git a/kernel/auditsc.c b/kernel/auditsc.c index 73f932b..31917ac 100644 --- a/kernel/auditsc.c +++ b/kernel/auditsc.c @@ -187,7 +187,8 @@ static struct list_head audit_filter_list[AUDIT_NR_FILTERS] = { LIST_HEAD_INIT(audit_filter_list[2]), LIST_HEAD_INIT(audit_filter_list[3]), LIST_HEAD_INIT(audit_filter_list[4]), -#if AUDIT_NR_FILTERS != 5 + LIST_HEAD_INIT(audit_filter_list[5]), +#if AUDIT_NR_FILTERS != 6 #error Fix audit_filter_list initialiser #endif }; @@ -663,6 +664,38 @@ int audit_filter_user(struct netlink_skb_parms *cb, int type) return ret; /* Audit by default */ } +int audit_filter_type(int type) +{ + struct audit_entry *e; + int result = 0; + + rcu_read_lock(); + if (list_empty(&audit_filter_list[AUDIT_FILTER_TYPE])) + goto unlock_and_return; + + list_for_each_entry_rcu(e, &audit_filter_list[AUDIT_FILTER_TYPE], + list) { + struct audit_rule *rule = &e->rule; + int i; + for (i = 0; i < rule->field_count; i++) { + u32 field = rule->fields[i] & ~AUDIT_OPERATORS; + u32 op = rule->fields[i] & AUDIT_OPERATORS; + u32 value = rule->values[i]; + if ( field == AUDIT_MSGTYPE ) { + result = audit_comparator(type, op, value); + if (!result) + break; + } + } + if (result) + goto unlock_and_return; + } +unlock_and_return: + rcu_read_unlock(); + return result; +} + + /* This should be called with task_lock() held. */ static inline struct audit_context *audit_get_context(struct task_struct *tsk, int return_valid, |