FAILED: patch "[PATCH] futex: Clear stale exiting pointer in futex_lock_pi() retry" failed to apply to 5.15-stable tree
Subsystems (2)
[email protected]
maintainerThe patch below does not apply to the 5.15-stable tree.
If someone wants it applied there, or to any other stable or longterm tree, then please email the backport, including the original git commit id to <[email protected]>.
To reproduce the conflict and resubmit, you may use the following commands:
git fetch https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git/ linux-5.15.y
git checkout FETCH_HEAD
git cherry-pick -x 210d36d892de5195e6766c45519dfb1e65f3eb83
# <resolve conflicts, build, test, etc.>
git commit -s
git send-email --to '<[email protected]>' --in-reply-to '2026033034-city-docile-1900@gregkh' --subject-prefix 'PATCH 5.15.y' HEAD^..
Possible dependencies:
thanks,
greg k-h
------------------ original commit in Linus's tree ------------------
From 210d36d892de5195e6766c45519dfb1e65f3eb83 Mon Sep 17 00:00:00 2001
From: Davidlohr Bueso <[email protected]>
Date: Wed, 25 Mar 2026 17:17:59 -0700
Subject: [PATCH] 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.
kernel/futex/pi.c +2 -1
@@ -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;
Thomas Gleixner
maintainerPATCH 1/1 futex: Clear stale exiting pointer in futex_lock_pi() retry
From: Davidlohr Bueso <[email protected]>
Commit 210d36d892de5195e6766c45519dfb1e65f3eb83 upstream.
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.
--- kernel/futex/core.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-)
---
kernel/futex/core.c +2 -1
@@ -3029,9 +3029,9 @@ static int futex_lock_pi(u32 __user *uad ktime_t *time, int trylock) {struct hrtimer_sleeper timeout, *to; -struct task_struct *exiting =NULL ;struct rt_mutex_waiter rt_waiter;struct futex_hash_bucket *hb; +struct task_struct *exiting;struct futex_q q = futex_q_init;int res, ret;
@@ -3044,6 +3044,7 @@ static int futex_lock_pi(u32 __user *uad to =futex_setup_timer (time, &timeout, flags,0 ); retry: + exiting =NULL ; ret =get_futex_key (uaddr, flags &FLAGS_SHARED , &q.key,FUTEX_WRITE );if (unlikely (ret !=0 )) goto out;