improve performance with many inode rules
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
@@ -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
@@ -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