Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

fsnotify: don't BUG in fsnotify_destroy_mark()

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>
CC: stable@vger.kernel.org
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>

authored by

Miklos Szeredi and committed by
Linus Torvalds
fed47485 1e6c4dfd

+5 -3
+5 -3
fs/notify/mark.c
··· 135 135 136 136 mark->flags &= ~FSNOTIFY_MARK_FLAG_ALIVE; 137 137 138 - /* 1 from caller and 1 for being on i_list/g_list */ 139 - BUG_ON(atomic_read(&mark->refcnt) < 2); 140 - 141 138 spin_lock(&group->mark_lock); 142 139 143 140 if (mark->flags & FSNOTIFY_MARK_FLAG_INODE) { ··· 177 180 178 181 if (inode && (mark->flags & FSNOTIFY_MARK_FLAG_OBJECT_PINNED)) 179 182 iput(inode); 183 + 184 + /* 185 + * We don't necessarily have a ref on mark from caller so the above iput 186 + * may have already destroyed it. Don't touch from now on. 187 + */ 180 188 181 189 /* 182 190 * it's possible that this group tried to destroy itself, but this