4.14-stable review patch. If anyone has any objections, please let me know. ------------------ From: Miklos Szeredi <mszeredi@xxxxxxxxxx> commit 9a31d7ad997f55768c687974ce36b759065b49e5 upstream. Blind increment of group's user_waits is not enough, we could be far enough in the group's destruction that it isn't taken into account (i.e. grabbing the mark ref afterwards doesn't guarantee that it was the ref coming from the _group_ that was grabbed). Instead we need to check (under lock) that the mark is still attached to the group after having obtained a ref to the mark. If not, skip it. Reviewed-by: Amir Goldstein <amir73il@xxxxxxxxx> Signed-off-by: Miklos Szeredi <mszeredi@xxxxxxxxxx> Fixes: 9385a84d7e1f ("fsnotify: Pass fsnotify_iter_info into handle_event handler") Signed-off-by: Jan Kara <jack@xxxxxxx> Signed-off-by: Greg Kroah-Hartman <gregkh@xxxxxxxxxxxxxxxxxxx> --- fs/notify/mark.c | 25 +++++++++++-------------- 1 file changed, 11 insertions(+), 14 deletions(-) --- a/fs/notify/mark.c +++ b/fs/notify/mark.c @@ -255,23 +255,20 @@ void fsnotify_put_mark(struct fsnotify_m */ static bool fsnotify_get_mark_safe(struct fsnotify_mark *mark) { - struct fsnotify_group *group; - if (!mark) return true; - group = mark->group; - /* - * Since acquisition of mark reference is an atomic op as well, we can - * be sure this inc is seen before any effect of refcount increment. - */ - atomic_inc(&group->user_waits); - if (atomic_inc_not_zero(&mark->refcnt)) - return true; - - if (atomic_dec_and_test(&group->user_waits) && group->shutdown) - wake_up(&group->notification_waitq); - + if (atomic_inc_not_zero(&mark->refcnt)) { + spin_lock(&mark->lock); + if (mark->flags & FSNOTIFY_MARK_FLAG_ATTACHED) { + /* mark is attached, group is still alive then */ + atomic_inc(&mark->group->user_waits); + spin_unlock(&mark->lock); + return true; + } + spin_unlock(&mark->lock); + fsnotify_put_mark(mark); + } return false; }