]> git.karo-electronics.de Git - karo-tx-linux.git/commitdiff
fsnotify: don't BUG in fsnotify_destroy_mark()
authorMiklos Szeredi <mszeredi@suse.cz>
Thu, 12 Jan 2012 16:59:46 +0000 (17:59 +0100)
committerGreg Kroah-Hartman <gregkh@suse.de>
Thu, 26 Jan 2012 00:13:33 +0000 (16:13 -0800)
commit fed474857efbed79cd390d0aee224231ca718f63 upstream.

Removing the parent of a watched file results in "kernel BUG at
fs/notify/mark.c:139".

To reproduce

  add "-w /tmp/audit/dir/watched_file" to audit.rules
  rm -rf /tmp/audit/dir

This is caused by fsnotify_destroy_mark() being called without an
extra reference taken by the caller.

Reported by Francesco Cosoleto here:

  https://bugzilla.novell.com/show_bug.cgi?id=689860

Fix by removing the BUG_ON and adding a comment about not accessing mark after
the iput.

Signed-off-by: Miklos Szeredi <mszeredi@suse.cz>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
fs/notify/mark.c

index e14587d55689dae3cedccd1d2afeb1242ab0947c..f104d565b6823aa75ab39c5c0717e9e3fd9382f3 100644 (file)
@@ -135,9 +135,6 @@ void fsnotify_destroy_mark(struct fsnotify_mark *mark)
 
        mark->flags &= ~FSNOTIFY_MARK_FLAG_ALIVE;
 
-       /* 1 from caller and 1 for being on i_list/g_list */
-       BUG_ON(atomic_read(&mark->refcnt) < 2);
-
        spin_lock(&group->mark_lock);
 
        if (mark->flags & FSNOTIFY_MARK_FLAG_INODE) {
@@ -181,6 +178,11 @@ void fsnotify_destroy_mark(struct fsnotify_mark *mark)
        if (inode && (mark->flags & FSNOTIFY_MARK_FLAG_OBJECT_PINNED))
                iput(inode);
 
+       /*
+        * We don't necessarily have a ref on mark from caller so the above iput
+        * may have already destroyed it.  Don't touch from now on.
+        */
+
        /*
         * it's possible that this group tried to destroy itself, but this
         * this mark was simultaneously being freed by inode.  If that's the