This is a note to let you know that I've just added the patch titled futex: Fix (possible) missed wakeup to the 4.9-stable tree which can be found at: http://www.kernel.org/git/?p=linux/kernel/git/stable/stable-queue.git;a=summary The filename of the patch is: futex-fix-possible-missed-wakeup.patch and it can be found in the queue-4.9 subdirectory. If you, or anyone else, feels it should not be added to the stable tree, please let <stable@xxxxxxxxxxxxxxx> know about it. >From foo@baz Mon Mar 29 07:48:09 AM CEST 2021 From: Ben Hutchings <ben@xxxxxxxxxxxxxxx> Date: Sun, 28 Mar 2021 22:42:32 +0200 Subject: futex: Fix (possible) missed wakeup To: stable@xxxxxxxxxxxxxxx Cc: Lee Jones <lee.jones@xxxxxxxxxx>, "Luis Claudio R. Goncalves" <lgoncalv@xxxxxxxxxx>, Florian Fainelli <f.fainelli@xxxxxxxxx> Message-ID: <YGDqOPquwh/m9sL9@xxxxxxxxxxxxxxx> Content-Disposition: inline From: Peter Zijlstra <peterz@xxxxxxxxxxxxx> commit b061c38bef43406df8e73c5be06cbfacad5ee6ad upstream. We must not rely on wake_q_add() to delay the wakeup; in particular commit: 1d0dcb3ad9d3 ("futex: Implement lockless wakeups") moved wake_q_add() before smp_store_release(&q->lock_ptr, NULL), which could result in futex_wait() waking before observing ->lock_ptr == NULL and going back to sleep again. Signed-off-by: Peter Zijlstra (Intel) <peterz@xxxxxxxxxxxxx> Cc: Linus Torvalds <torvalds@xxxxxxxxxxxxxxxxxxxx> Cc: Peter Zijlstra <peterz@xxxxxxxxxxxxx> Cc: Thomas Gleixner <tglx@xxxxxxxxxxxxx> Fixes: 1d0dcb3ad9d3 ("futex: Implement lockless wakeups") Signed-off-by: Ingo Molnar <mingo@xxxxxxxxxx> Signed-off-by: Sasha Levin <sashal@xxxxxxxxxx> Signed-off-by: Ben Hutchings <ben@xxxxxxxxxxxxxxx> Signed-off-by: Greg Kroah-Hartman <gregkh@xxxxxxxxxxxxxxxxxxx> --- kernel/futex.c | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) --- a/kernel/futex.c +++ b/kernel/futex.c @@ -1553,11 +1553,7 @@ static void mark_wake_futex(struct wake_ if (WARN(q->pi_state || q->rt_waiter, "refusing to wake PI futex\n")) return; - /* - * Queue the task for later wakeup for after we've released - * the hb->lock. wake_q_add() grabs reference to p. - */ - wake_q_add(wake_q, p); + get_task_struct(p); __unqueue_futex(q); /* * The waiting task can free the futex_q as soon as @@ -1566,6 +1562,13 @@ static void mark_wake_futex(struct wake_ * store to lock_ptr from getting ahead of the plist_del. */ smp_store_release(&q->lock_ptr, NULL); + + /* + * Queue the task for later wakeup for after we've released + * the hb->lock. wake_q_add() grabs reference to p. + */ + wake_q_add(wake_q, p); + put_task_struct(p); } /* Patches currently in stable-queue which might be from ben@xxxxxxxxxxxxxxx are queue-4.9/futex-drop-hb-lock-before-enqueueing-on-the-rtmutex.patch queue-4.9/futex-rework-futex_lock_pi-to-use-rt_mutex_-_proxy_lock.patch queue-4.9/futex-avoid-freeing-an-active-timer.patch queue-4.9/futex-rt_mutex-introduce-rt_mutex_init_waiter.patch queue-4.9/futex-fix-incorrect-should_fail_futex-handling.patch queue-4.9/futex-rt_mutex-fix-rt_mutex_cleanup_proxy_lock.patch queue-4.9/futex-use-smp_store_release-in-mark_wake_futex.patch queue-4.9/futex-fix-possible-missed-wakeup.patch queue-4.9/locking-futex-allow-low-level-atomic-operations-to-return-eagain.patch queue-4.9/futex-prevent-robust-futex-exit-race.patch queue-4.9/futex-handle-transient-ownerless-rtmutex-state-correctly.patch queue-4.9/futex-handle-early-deadlock-return-correctly.patch queue-4.9/arm64-futex-bound-number-of-ldxr-stxr-loops-in-futex_wake_op.patch