Commit 210d36d892de for kernel

commit 210d36d892de5195e6766c45519dfb1e65f3eb83
Author: Davidlohr Bueso <dave@stgolabs.net>
Date:   Wed Mar 25 17:17:59 2026 -0700

    futex: Clear stale exiting pointer in futex_lock_pi() retry path

    Fuzzying/stressing futexes triggered:

        WARNING: kernel/futex/core.c:825 at wait_for_owner_exiting+0x7a/0x80, CPU#11: futex_lock_pi_s/524

    When futex_lock_pi_atomic() sees the owner is exiting, it returns -EBUSY
    and stores a refcounted task pointer in 'exiting'.

    After wait_for_owner_exiting() consumes that reference, the local pointer
    is never reset to nil. Upon a retry, if futex_lock_pi_atomic() returns a
    different error, the bogus pointer is passed to wait_for_owner_exiting().

      CPU0                       CPU1                      CPU2
      futex_lock_pi(uaddr)
      // acquires the PI futex
      exit()
        futex_cleanup_begin()
          futex_state = EXITING;
                                 futex_lock_pi(uaddr)
                                   futex_lock_pi_atomic()
                                     attach_to_pi_owner()
                                       // observes EXITING
                                       *exiting = owner;  // takes ref
                                       return -EBUSY
                                   wait_for_owner_exiting(-EBUSY, owner)
                                     put_task_struct();   // drops ref
                                   // exiting still points to owner
                                   goto retry;
                                   futex_lock_pi_atomic()
                                     lock_pi_update_atomic()
                                       cmpxchg(uaddr)
                                            *uaddr ^= WAITERS // whatever
                                       // value changed
                                     return -EAGAIN;
                                   wait_for_owner_exiting(-EAGAIN, exiting) // stale
                                     WARN_ON_ONCE(exiting)

    Fix this by resetting upon retry, essentially aligning it with requeue_pi.

    Fixes: 3ef240eaff36 ("futex: Prevent exit livelock")
    Signed-off-by: Davidlohr Bueso <dave@stgolabs.net>
    Signed-off-by: Thomas Gleixner <tglx@kernel.org>
    Cc: stable@vger.kernel.org
    Link: https://patch.msgid.link/20260326001759.4129680-1-dave@stgolabs.net

diff --git a/kernel/futex/pi.c b/kernel/futex/pi.c
index bc1f7e83a37e..7808068fa59e 100644
--- a/kernel/futex/pi.c
+++ b/kernel/futex/pi.c
@@ -918,7 +918,7 @@ int fixup_pi_owner(u32 __user *uaddr, struct futex_q *q, int locked)
 int futex_lock_pi(u32 __user *uaddr, unsigned int flags, ktime_t *time, int trylock)
 {
 	struct hrtimer_sleeper timeout, *to;
-	struct task_struct *exiting = NULL;
+	struct task_struct *exiting;
 	struct rt_mutex_waiter rt_waiter;
 	struct futex_q q = futex_q_init;
 	DEFINE_WAKE_Q(wake_q);
@@ -933,6 +933,7 @@ int futex_lock_pi(u32 __user *uaddr, unsigned int flags, ktime_t *time, int tryl
 	to = futex_setup_timer(time, &timeout, flags, 0);

 retry:
+	exiting = NULL;
 	ret = get_futex_key(uaddr, flags, &q.key, FUTEX_WRITE);
 	if (unlikely(ret != 0))
 		goto out;