Skip to contentSkip to conversation

improve performance with many inode rules

PATCH New Amy Griffis 1 participant 1 message May 4, 2006 Audit

lore
Share & tools
lore
#0 lore raw

PATCH 1/1 improve performance with many inode rules

The following patch improves audit syscall filtering performance when the exit filter list contains many rules with an inode number field. This implements Al Viro's idea from:
https://www.redhat.com/archives/linux-audit/2006-April/msg00087.html

Rules containing a single inode field are placed in one of 32 lists, determined by hashing the inode number. Rules containing more than one inode field, or using an operator other than equality, remain in the exit filter list.

At syscall exit time, rules in the exit filter list are evaluated first. The inode number hash is then checked for matching rules if any audit_names[] have been collected during syscall processing.

--

 audit.c       |    8 ++
 audit.h       |   11 +++
 auditfilter.c |  168 +++++++++++++++++++++++++++++++++++++++++++++-------------
 auditsc.c     |   96 +++++++++++++++++++++++----------
 4 files changed, 218 insertions(+), 65 deletions(-)
kernel/audit.c +8 -0
index 7637410..40b3807 100644
@@ -106,6 +106,9 @@ static struct sock *audit_sock;
 /* Inotify handle. */
 struct inotify_handle *audit_ih;
 
+/* Hash for inode-based rules */
+struct list_head audit_inode_hash[AUDIT_INODE_BUCKETS];
+
 /* The audit_freelist is a list of pre-allocated audit buffers (if more
  * than AUDIT_MAXFREE are in use, the audit buffer is freed instead of
  * being placed on the freelist). */
@@ -669,6 +672,8 @@ static void audit_receive(struct sock *s
 /* Initialize audit support at boot time. */
 static int __init audit_init(void)
 {
+	int i;
+
 	printk(KERN_INFO "audit: initializing netlink socket (%s)\n",
 	       audit_default ? "enabled" : "disabled");
 	audit_sock = netlink_kernel_create(NETLINK_AUDIT, 0, audit_receive,
@@ -692,6 +697,9 @@ #ifdef CONFIG_AUDITSYSCALL
 	audit_ih = inotify_init(audit_handle_ievent);
 	if (IS_ERR(audit_ih))
 		audit_panic("cannot initialize inotify handle");
+
+	for (i = 0; i < AUDIT_INODE_BUCKETS; i++)
+		INIT_LIST_HEAD(&audit_inode_hash[i]);
 #endif
 
 	return 0;
kernel/audit.h +10 -1
index 771833d..507998a 100644
@@ -81,6 +81,7 @@ struct audit_krule {
 	u32			buflen; /* for data alloc on list rules */
 	u32			field_count;
 	struct audit_field	*fields;
+	struct audit_field	*inode_f; /* quick access to an inode field */
 	struct audit_watch	*watch;	/* associated watch */
 	struct list_head	rlist;	/* entry in audit_watch.rules list */
 };
@@ -91,8 +92,16 @@ struct audit_entry {
 	struct audit_krule	rule;
 };
 
-
 extern int audit_pid;
+
+#define AUDIT_INODE_BUCKETS	32
+extern struct list_head audit_inode_hash[AUDIT_INODE_BUCKETS];
+
+static inline int audit_hash_ino(u32 ino)
+{
+	return (ino & (AUDIT_INODE_BUCKETS-1));
+}
+
 extern int audit_comparator(const u32 left, const u32 op, const u32 right);
 extern int audit_compare_dname_path(const char *dname, const char *path);
 extern struct sk_buff *	    audit_make_reply(int pid, int seq, int type,
kernel/auditfilter.c +132 -36

265 lines not on this page · raw message

kernel/auditsc.c +68 -28

154 lines not on this page · raw message