For deleting the fsnotify_mark related with an inode, there are 2 paths in the kernel. When the inotify fd is closed, all the marks belonging to a group are removed one by one in fsnotify_clear_marks_by_group_flags. Other path is when the inode is removed from user space by unlink, fsnotify_destroy_mark is called to delete a single mark. There is a race between these 2 paths which is caused due to the temporary release of the mark_mutex inside fsnotify_destroy_mark_locked. The race happen when the inotify app monitoring the file(s) exits, triggering fsnotify_clear_marks_by_group_flags to delete the marks. This function use lmark pointer to move to the next node after a safe removal of the node. In parallel, if there is rm call for a file and such that the lmark is pointing to the mark which is removed by this rm call, lmark ends up pointing to a freed memory. Now, when we try to move to the next node using lmark, it triggers an invalid virtual address crash. Although fsnotify_clear_marks_by_group_flags and fsnotify_destroy_mark are synchronized by mark_mutex, but both of these functions call fsnotify_destroy_mark_locked which release the mark_mutex and acquire it again creating a subtle race window. There seems to be no reason for releasing mark_mutex, so this patch remove the mutex_unlock call. Signed-off-by: Ashish Sangwan <a.sangwan@xxxxxxxxxxx> Reviewed-by: Amit Sahrawat <a.sahrawat@xxxxxxxxxxx> --- fs/notify/mark.c | 4 ---- 1 files changed, 0 insertions(+), 4 deletions(-) diff --git a/fs/notify/mark.c b/fs/notify/mark.c index 92e48c7..4ee419f 100755 --- a/fs/notify/mark.c +++ b/fs/notify/mark.c @@ -157,8 +157,6 @@ void fsnotify_destroy_mark_locked(struct fsnotify_mark *mark, if (inode && (mark->flags & FSNOTIFY_MARK_FLAG_OBJECT_PINNED)) iput(inode); - /* release lock temporarily */ - mutex_unlock(&group->mark_mutex); spin_lock(&destroy_lock); list_add(&mark->g_list, &destroy_list); @@ -191,8 +189,6 @@ void fsnotify_destroy_mark_locked(struct fsnotify_mark *mark, */ atomic_dec(&group->num_marks); - - mutex_lock_nested(&group->mark_mutex, SINGLE_DEPTH_NESTING); } void fsnotify_destroy_mark(struct fsnotify_mark *mark, -- 1.7.7 -- To unsubscribe from this list: send the line "unsubscribe linux-fsdevel" in