[PATCH] auditfs updates to .46

David Woodhouse dwmw2 at infradead.org
Wed May 25 15:59:10 UTC 2005


On Wed, 2005-05-25 at 10:33 -0500, Timothy R. Chavez wrote:
> > I like your little macro.
> >
> 
> Yikes, that sounds a bit dirty.  My bad. ;)

:)

What I'm doing with it _is_ a bit dirty. Looks something like this.

It compiles but I haven't tested it yet or even really done a second
read through the code -- I have to be home on time today :)

It's very loosely based on Serge's patch to use a hash table for all
security objects, although I think only the module_param() line actually
survives from the original, and even that can probably go too.

--- linux-2.6.9/include/linux/audit.h~	2005-05-25 15:56:32.000000000 +0100
+++ linux-2.6.9/include/linux/audit.h	2005-05-25 16:28:08.000000000 +0100
@@ -215,6 +215,8 @@ struct watch_transport {
 /* Structure associated with inode->i_audit */
 
 struct audit_inode_data {
+	struct audit_inode_data *next_hash;
+	struct inode		*inode;
 	struct audit_wentry	*wentry;
 	struct hlist_head 	watchlist;
 	rwlock_t		lock;
--- linux-2.6.9/include/linux/fs.h~	2005-05-25 14:30:18.000000000 +0100
+++ linux-2.6.9/include/linux/fs.h	2005-05-25 16:46:27.000000000 +0100
@@ -462,7 +462,6 @@ struct inode {
 	unsigned long		i_dnotify_mask; /* Directory notify events */
 	struct dnotify_struct	*i_dnotify; /* for directory notifications */
 
-	struct audit_inode_data	*i_audit;
 	unsigned long		i_state;
 	unsigned long		dirtied_when;	/* jiffies of first dirtying */
 
--- linux-2.6.9/fs/inode.c~	2005-05-25 14:30:18.000000000 +0100
+++ linux-2.6.9/fs/inode.c	2005-05-25 16:47:35.000000000 +0100
@@ -135,7 +135,6 @@ static struct inode *alloc_inode(struct 
 		inode->i_bdev = NULL;
 		inode->i_cdev = NULL;
 		inode->i_rdev = 0;
-		inode->i_audit = NULL;
 		inode->i_security = NULL;
 		inode->dirtied_when = 0;
 		if (audit_inode_alloc(inode) || security_inode_alloc(inode)) {
--- linux-2.6.9/kernel/auditfs.c~	2005-05-25 15:56:32.000000000 +0100
+++ linux-2.6.9/kernel/auditfs.c	2005-05-25 16:44:10.000000000 +0100
@@ -30,8 +30,10 @@
 #include <linux/namei.h>
 #include <linux/mount.h>
 #include <linux/list.h>
+#include <linux/hash.h>
 #include <linux/slab.h>
 #include <linux/audit.h>
+#include <linux/module.h>
 #include <asm/uaccess.h>
 
 
@@ -50,8 +52,32 @@ struct audit_skb_list {
        size_t size;
 };
 
-#define inode_audit_data(inode) ((inode)->i_audit)
 
+static struct audit_inode_data **auditfs_hash_table;
+static spinlock_t auditfs_hash_lock = SPIN_LOCK_UNLOCKED;
+static int auditfs_hash_bits;
+static int auditfs_cache_buckets = 16384;
+module_param(auditfs_cache_buckets, int, 0);
+MODULE_PARM_DESC(auditfs_cache_buckets, "Number of auditfs cache entries to allocate (default 16384)\n");
+
+struct audit_inode_data *inode_audit_data(struct inode *inode)
+{
+	struct audit_inode_data **list;
+	int h = hash_ptr(inode, auditfs_hash_bits);
+	struct audit_inode_data *ret = NULL;
+
+	list = &auditfs_hash_table[h];
+	spin_lock(&auditfs_hash_lock);
+
+	while (*list && (unsigned long)((*list)->inode) < (unsigned long)inode)
+		list = &(*list)->next_hash;
+
+	if (*list && (*list)->inode == inode)
+		ret = *list;
+
+	spin_unlock(&auditfs_hash_lock);
+	return ret;
+}
 
 /* Private Interface */
 
@@ -371,19 +397,6 @@ static inline void audit_drain_watchlist
 		audit_destroy_wentry(wentry);
 }
 
-static inline struct audit_inode_data *audit_data_alloc(void)
-{
-	struct audit_inode_data *data;
-
-	data = kmalloc(sizeof(struct audit_inode_data), GFP_KERNEL);
-	if (data) {
-		data->wentry = NULL;
-		INIT_HLIST_HEAD(&data->watchlist);
-		data->lock = RW_LOCK_UNLOCKED;
-	}
-
-	return data;
-}
 
 static inline void audit_data_free(struct audit_inode_data *data)
 {
@@ -659,20 +672,58 @@ audit_receive_watch_exit:
 
 int audit_inode_alloc(struct inode *inode)
 {
-	if (inode) {
-		inode_audit_data(inode) = audit_data_alloc();
-		if (!inode_audit_data(inode))
-			return ENOMEM;
-	}
+	struct audit_inode_data *data;
+	struct audit_inode_data **list;
+	int h = hash_ptr(inode, auditfs_hash_bits);
 
+	data = kmalloc(sizeof(struct audit_inode_data), GFP_KERNEL);
+	if (!data)
+		return -ENOMEM;
+
+	INIT_HLIST_HEAD(&data->watchlist);
+	data->wentry = NULL;
+	data->lock = RW_LOCK_UNLOCKED;
+	data->inode = inode;
+	data->next_hash = NULL;
+
+	/* Add it to the hash table */
+	list = &auditfs_hash_table[h];
+	spin_lock(&auditfs_hash_lock);
+
+	while (*list && (unsigned long)((*list)->inode) < (unsigned long)inode)
+		list = &(*list)->next_hash;
+
+	data->next_hash = *list;
+	*list = data;
+
+	spin_unlock(&auditfs_hash_lock);
 	return 0;
 }
 
 void audit_inode_free(struct inode *inode)
 {
-	if (inode)
-		audit_data_free(inode_audit_data(inode));
+	struct audit_inode_data *data = NULL;
+	int h = hash_ptr(inode, auditfs_hash_bits);
+	struct audit_inode_data **list;
+
+	if (!inode)
+		return;
+
+	spin_lock(&auditfs_hash_lock);
+	list = &auditfs_hash_table[h];
+	while (*list && (unsigned long)((*list)->inode) < (unsigned long)inode)
+		list = &(*list)->next_hash;
+
+	if (*list && (*list)->inode == inode) {
+		data = *list;
+		*list = data->next_hash;
+	}
+	spin_unlock(&auditfs_hash_lock);
+
+	if (data)
+		audit_data_free(data);
 }
+
 /*
  * When we delete a dentry we check to see whether or not we're being
  * watched.  If we are watched, we have to put back our reference to
@@ -712,6 +763,25 @@ int audit_filesystem_init(void)
 	if (!audit_wentry_cache)
 		goto audit_filesystem_init_fail;
 
+	/* Set up hash table for inode objects */
+	auditfs_hash_bits = long_log2(auditfs_cache_buckets);
+	if (auditfs_cache_buckets != (1 << auditfs_hash_bits)) {
+		auditfs_hash_bits++;
+		auditfs_cache_buckets = 1 << auditfs_hash_bits;
+		printk(KERN_NOTICE
+		       "%s: auditfs_cache_buckets set to %d (bits %d)\n",
+		       __FUNCTION__, auditfs_cache_buckets, auditfs_hash_bits);
+	}
+
+	auditfs_hash_table = kmalloc(auditfs_cache_buckets * sizeof(void *), GFP_KERNEL);
+
+	if (!auditfs_hash_table) {
+		printk(KERN_NOTICE "No memory to initialize auditfs cache.\n");
+		goto audit_filesystem_init_fail;
+	}
+
+	memset(auditfs_hash_table, 0, auditfs_cache_buckets * sizeof(void *));
+
 	ret = 0;
 	goto audit_filesystem_init_exit;
 


-- 
dwmw2




More information about the Linux-audit mailing list