On Wed, 2005-11-02 at 10:30 -0600, Dustin Kirkland wrote:
On 11/2/05, Steve Grubb <sgrubb(a)redhat.com> wrote:
> On Tuesday 01 November 2005 17:53, Dustin Kirkland wrote:
> > - 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.
>
> You should check that the list is empty and short circuit. This will be the
> case %99.99 of the time.
Ok. There's now a list_empty() check at the top of
audit_filter_exclude().
I also removed some unnecessary {} and fixed a couple of lines that were
>80 characters.
I duly note that there's an existing discussion as to whether this
filter belongs in the kernel or in userspace at all. But I'm keeping
the patch current with existing comments.
Updated patch here.
There was an error in that patch (inadvertent sizeof() call--sent the
wrong version of the patch). Correct patch here.
diff -uprN 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 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 -uprN 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-02 04:44:40.000000000 -0600
@@ -659,6 +659,9 @@ 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 -uprN 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-02 10:12:04.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,36 @@ 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();
+ if (list_empty(&audit_filter_list[AUDIT_FILTER_EXCLUDE]))
+ goto unlock_and_return;
+
+ 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)
+ 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,