Patch "futex: Resend potentially swallowed owner death notification" has been added to the 5.10-stable tree

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



This is a note to let you know that I've just added the patch titled

    futex: Resend potentially swallowed owner death notification

to the 5.10-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-resend-potentially-swallowed-owner-death-notif.patch
and it can be found in the queue-5.10 subdirectory.

If you, or anyone else, feels it should not be added to the stable tree,
please let <stable@xxxxxxxxxxxxxxx> know about it.



commit 2f6d7b2a0a2358b66df16f6e52c7a91facb93aa3
Author: Alexey Izbyshev <izbyshev@xxxxxxxxx>
Date:   Sat Nov 12 00:54:39 2022 +0300

    futex: Resend potentially swallowed owner death notification
    
    [ Upstream commit 90d758896787048fa3d4209309d4800f3920e66f ]
    
    Commit ca16d5bee598 ("futex: Prevent robust futex exit race") addressed
    two cases when tasks waiting on a robust non-PI futex remained blocked
    despite the futex not being owned anymore:
    
    * if the owner died after writing zero to the futex word, but before
      waking up a waiter
    
    * if a task waiting on the futex was woken up, but died before updating
      the futex word (effectively swallowing the notification without acting
      on it)
    
    In the second case, the task could be woken up either by the previous
    owner (after the futex word was reset to zero) or by the kernel (after
    the OWNER_DIED bit was set and the TID part of the futex word was reset
    to zero) if the previous owner died without the resetting the futex.
    
    Because the referenced commit wakes up a potential waiter only if the
    whole futex word is zero, the latter subcase remains unaddressed.
    
    Fix this by looking only at the TID part of the futex when deciding
    whether a wake up is needed.
    
    Fixes: ca16d5bee598 ("futex: Prevent robust futex exit race")
    Signed-off-by: Alexey Izbyshev <izbyshev@xxxxxxxxx>
    Signed-off-by: Thomas Gleixner <tglx@xxxxxxxxxxxxx>
    Acked-by: Peter Zijlstra (Intel) <peterz@xxxxxxxxxxxxx>
    Link: https://lore.kernel.org/r/20221111215439.248185-1-izbyshev@xxxxxxxxx
    Signed-off-by: Sasha Levin <sashal@xxxxxxxxxx>

diff --git a/kernel/futex/core.c b/kernel/futex/core.c
index 26ca79c47480..8dd0bc50ac36 100644
--- a/kernel/futex/core.c
+++ b/kernel/futex/core.c
@@ -3405,6 +3405,7 @@ static int handle_futex_death(u32 __user *uaddr, struct task_struct *curr,
 			      bool pi, bool pending_op)
 {
 	u32 uval, nval, mval;
+	pid_t owner;
 	int err;
 
 	/* Futex address must be 32bit aligned */
@@ -3426,6 +3427,10 @@ static int handle_futex_death(u32 __user *uaddr, struct task_struct *curr,
 	 * 2. A woken up waiter is killed before it can acquire the
 	 *    futex in user space.
 	 *
+	 * In the second case, the wake up notification could be generated
+	 * by the unlock path in user space after setting the futex value
+	 * to zero or by the kernel after setting the OWNER_DIED bit below.
+	 *
 	 * In both cases the TID validation below prevents a wakeup of
 	 * potential waiters which can cause these waiters to block
 	 * forever.
@@ -3434,24 +3439,27 @@ static int handle_futex_death(u32 __user *uaddr, struct task_struct *curr,
 	 *
 	 *	1) task->robust_list->list_op_pending != NULL
 	 *	   @pending_op == true
-	 *	2) User space futex value == 0
+	 *	2) The owner part of user space futex value == 0
 	 *	3) Regular futex: @pi == false
 	 *
 	 * If these conditions are met, it is safe to attempt waking up a
 	 * potential waiter without touching the user space futex value and
-	 * trying to set the OWNER_DIED bit. The user space futex value is
-	 * uncontended and the rest of the user space mutex state is
-	 * consistent, so a woken waiter will just take over the
-	 * uncontended futex. Setting the OWNER_DIED bit would create
-	 * inconsistent state and malfunction of the user space owner died
-	 * handling.
-	 */
-	if (pending_op && !pi && !uval) {
+	 * trying to set the OWNER_DIED bit. If the futex value is zero,
+	 * the rest of the user space mutex state is consistent, so a woken
+	 * waiter will just take over the uncontended futex. Setting the
+	 * OWNER_DIED bit would create inconsistent state and malfunction
+	 * of the user space owner died handling. Otherwise, the OWNER_DIED
+	 * bit is already set, and the woken waiter is expected to deal with
+	 * this.
+	 */
+	owner = uval & FUTEX_TID_MASK;
+
+	if (pending_op && !pi && !owner) {
 		futex_wake(uaddr, 1, 1, FUTEX_BITSET_MATCH_ANY);
 		return 0;
 	}
 
-	if ((uval & FUTEX_TID_MASK) != task_pid_vnr(curr))
+	if (owner != task_pid_vnr(curr))
 		return 0;
 
 	/*



[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Index of Archives]     [Linux USB Devel]     [Linux Audio Users]     [Yosemite News]     [Linux Kernel]     [Linux SCSI]

  Powered by Linux