Kernel patch is pretty simple, straightforward...
- 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.
Comments welcome.
:-Dustin
diff -urpN linux-2.6.14-rc4-audit_ops/include/linux/audit.h
linux-2.6.14-rc4-audit_ops-exclude/include/linux/audit.h
--- linux-2.6.14-rc4-audit_ops/include/linux/audit.h 2005-10-26 16:12:42.000000000 -0500
+++ linux-2.6.14-rc4-audit_ops-exclude/include/linux/audit.h 2005-10-31 15:51:02.000000000
-0600
@@ -81,8 +81,9 @@
#define AUDIT_FILTER_ENTRY 0x02 /* Apply rule at syscall entry */
#define AUDIT_FILTER_WATCH 0x03 /* Apply rule to file system watches */
#define AUDIT_FILTER_EXIT 0x04 /* Apply rule at syscall exit */
+#define AUDIT_FILTER_EXCLUDE 0x05 /* Apply rule early, at audit_log_start */
-#define AUDIT_NR_FILTERS 5
+#define AUDIT_NR_FILTERS 6
#define AUDIT_FILTER_PREPEND 0x10 /* Prepend to front of list */
@@ -121,6 +122,7 @@
#define AUDIT_LOGINUID 9
#define AUDIT_PERS 10
#define AUDIT_ARCH 11
+#define AUDIT_MSGTYPE 12
/* These are ONLY useful when checking
* at syscall exit time (AUDIT_AT_EXIT). */
@@ -265,6 +267,7 @@ extern int audit_sockaddr(int len, void
extern int audit_avc_path(struct dentry *dentry, struct vfsmount *mnt);
extern void audit_signal_info(int sig, struct task_struct *t);
extern int audit_filter_user(struct netlink_skb_parms *cb, int type);
+extern int audit_filter_exclude(int type);
#else
#define audit_alloc(t) ({ 0; })
#define audit_free(t) do { ; } while (0)
diff -urpN linux-2.6.14-rc4-audit_ops/kernel/audit.c
linux-2.6.14-rc4-audit_ops-exclude/kernel/audit.c
--- linux-2.6.14-rc4-audit_ops/kernel/audit.c 2005-10-21 12:35:50.000000000 -0500
+++ linux-2.6.14-rc4-audit_ops-exclude/kernel/audit.c 2005-11-01 16:01:57.000000000 -0600
@@ -659,6 +659,10 @@ struct audit_buffer *audit_log_start(str
if (!audit_initialized)
return NULL;
+ if (unlikely(audit_filter_exclude(type))) {
+ return NULL;
+ }
+
if (gfp_mask & __GFP_WAIT)
reserve = 0;
else
diff -urpN linux-2.6.14-rc4-audit_ops/kernel/auditsc.c
linux-2.6.14-rc4-audit_ops-exclude/kernel/auditsc.c
--- linux-2.6.14-rc4-audit_ops/kernel/auditsc.c 2005-10-27 14:17:41.000000000 -0500
+++ linux-2.6.14-rc4-audit_ops-exclude/kernel/auditsc.c 2005-11-01 14:02:25.000000000
-0600
@@ -181,7 +181,8 @@ static struct list_head audit_filter_lis
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,33 @@ int audit_filter_user(struct netlink_skb
return ret; /* Audit by default */
}
+int audit_filter_exclude(int type)
+{
+ struct audit_entry *e;
+ int result = 0;
+
+ rcu_read_lock();
+ list_for_each_entry_rcu(e, &audit_filter_list[AUDIT_FILTER_EXCLUDE], 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) {
+ rcu_read_unlock();
+ return result;
+ }
+ }
+ }
+ }
+ 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,