提交 9a31d7ad 编写于 作者: M Miklos Szeredi 提交者: Jan Kara

fsnotify: fix pinning group in fsnotify_prepare_user_wait()

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: NAmir Goldstein <amir73il@gmail.com>
Signed-off-by: NMiklos Szeredi <mszeredi@redhat.com>
Fixes: 9385a84d ("fsnotify: Pass fsnotify_iter_info into handle_event handler")
Cc: <stable@vger.kernel.org> # v4.12
Signed-off-by: NJan Kara <jack@suse.cz>
上级 0d6ec079
...@@ -255,23 +255,20 @@ void fsnotify_put_mark(struct fsnotify_mark *mark) ...@@ -255,23 +255,20 @@ void fsnotify_put_mark(struct fsnotify_mark *mark)
*/ */
static bool fsnotify_get_mark_safe(struct fsnotify_mark *mark) static bool fsnotify_get_mark_safe(struct fsnotify_mark *mark)
{ {
struct fsnotify_group *group;
if (!mark) if (!mark)
return true; return true;
group = mark->group; if (atomic_inc_not_zero(&mark->refcnt)) {
/* spin_lock(&mark->lock);
* Since acquisition of mark reference is an atomic op as well, we can if (mark->flags & FSNOTIFY_MARK_FLAG_ATTACHED) {
* be sure this inc is seen before any effect of refcount increment. /* mark is attached, group is still alive then */
*/ atomic_inc(&mark->group->user_waits);
atomic_inc(&group->user_waits); spin_unlock(&mark->lock);
if (atomic_inc_not_zero(&mark->refcnt))
return true; return true;
}
if (atomic_dec_and_test(&group->user_waits) && group->shutdown) spin_unlock(&mark->lock);
wake_up(&group->notification_waitq); fsnotify_put_mark(mark);
}
return false; return false;
} }
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册