Sophie

Sophie

distrib > Scientific%20Linux > 5x > x86_64 > by-pkgid > 27922b4260f65d317aabda37e42bbbff > files > 248

kernel-2.6.18-238.el5.src.rpm

From: Alexander Viro <aviro@redhat.com>
Subject: [RHEL 5.1 PATCH] bz#251160
Date: Tue, 7 Aug 2007 19:10:00 -0400
Bugzilla: 251160
Message-Id: <20070807231000.GX13539@devserv.devel.redhat.com>
Changelog: [audit] sub-tree memory leaks


	Fixes a couple of leaks and off-by-one in allocator.  The
patch is on top of fixes for 248416.

diff -urN linux-2.6.18.x86_64/kernel/auditfilter.c linux-2.6.18.x86_64-1/kernel/auditfilter.c
--- linux-2.6.18.x86_64/kernel/auditfilter.c	2007-08-07 17:11:01.000000000 -0400
+++ linux-2.6.18.x86_64-1/kernel/auditfilter.c	2007-08-07 17:09:23.000000000 -0400
@@ -629,10 +629,9 @@
 			entry->rule.buflen += f->val;
 
 			err = audit_make_tree(&entry->rule, str, f->op);
-			if (err) {
-				kfree(str);
+			kfree(str);
+			if (err)
 				goto exit_free;
-			}
 			break;
 		case AUDIT_INODE:
 			err = audit_to_inode(&entry->rule, f);
diff -urN linux-2.6.18.x86_64/kernel/audit_tree.c linux-2.6.18.x86_64-1/kernel/audit_tree.c
--- linux-2.6.18.x86_64/kernel/audit_tree.c	2007-08-07 17:11:01.000000000 -0400
+++ linux-2.6.18.x86_64-1/kernel/audit_tree.c	2007-08-07 17:14:48.000000000 -0400
@@ -70,7 +70,7 @@
 {
 	struct audit_tree *tree;
 
-	tree = kmalloc(sizeof(struct audit_tree) + strlen(s), GFP_KERNEL);
+	tree = kmalloc(sizeof(struct audit_tree) + strlen(s) + 1, GFP_KERNEL);
 	if (tree) {
 		atomic_set(&tree->count, 1);
 		tree->goner = 0;
@@ -195,7 +195,6 @@
 
 /* tagging and untagging inodes with trees */
 
-/* ->inotify_mutex is held */
 static void untag_chunk(struct audit_chunk *chunk, struct node *p)
 {
 	struct audit_chunk *new;
@@ -203,8 +202,11 @@
 	int size = chunk->count - 1;
 	int i, j;
 
-	if (chunk->dead)
+	mutex_lock(&chunk->watch.inode->inotify_mutex);
+	if (chunk->dead) {
+		mutex_unlock(&chunk->watch.inode->inotify_mutex);
 		return;
+	}
 
 	owner = p->owner;
 
@@ -218,6 +220,8 @@
 		list_del_rcu(&chunk->hash);
 		spin_unlock(&hash_lock);
 		inotify_evict_watch(&chunk->watch);
+		mutex_unlock(&chunk->watch.inode->inotify_mutex);
+		put_inotify_watch(&chunk->watch);
 		return;
 	}
 
@@ -258,6 +262,8 @@
 		owner->root = new;
 	spin_unlock(&hash_lock);
 	inotify_evict_watch(&chunk->watch);
+	mutex_unlock(&chunk->watch.inode->inotify_mutex);
+	put_inotify_watch(&chunk->watch);
 	return;
 
 Fallback:
@@ -271,6 +277,7 @@
 	p->owner = NULL;
 	put_tree(owner);
 	spin_unlock(&hash_lock);
+	mutex_unlock(&chunk->watch.inode->inotify_mutex);
 }
 
 static int create_chunk(struct inode *inode, struct audit_tree *tree)
@@ -432,9 +439,7 @@
 		get_inotify_watch(&chunk->watch);
 		spin_unlock(&hash_lock);
 
-		mutex_lock(&chunk->watch.inode->inotify_mutex);
 		untag_chunk(chunk, p);
-		mutex_unlock(&chunk->watch.inode->inotify_mutex);
 
 		put_inotify_watch(&chunk->watch);
 		spin_lock(&hash_lock);
@@ -477,9 +482,7 @@
 		get_inotify_watch(&chunk->watch);
 		spin_unlock(&hash_lock);
 
-		mutex_lock(&chunk->watch.inode->inotify_mutex);
 		untag_chunk(chunk, node);
-		mutex_unlock(&chunk->watch.inode->inotify_mutex);
 
 		put_inotify_watch(&chunk->watch);
 		spin_lock(&hash_lock);