CVE-2026-90003: futex: Prevent rcuwait use-after-free during requeue PI
In the Linux kernel, the following vulnerability has been resolved:
futex: Prevent rcuwait use-after-free during requeue PI
On PREEMPTRT, FUTEXCMPREQUEUEPI can trigger a KASAN report (slab-out-of-bounds) in futexrequeuepicomplete() invocation of rcuwaitwakeup().
The futexq used by futexwaitrequeuepi() is allocated on the waiter's stack. An early wakeup can race with a PI requeue as follows:
waiter requeue task ------ ------------ futexwaitrequeuepi() futexdowait() schedule() futexrequeue futexproxytrylockatomic() futexrequeuepiprepare() QREQUEUEPINONE -> QREQUEUEPIINPROGRESS timeout/ signal wakes waiter futexrequeuepiwakeupsync() QREQUEUEPIINPROGRESS -> QREQUEUEPIWAIT requeuepiwakefutex futexrequeuepicomplete() cmpxchg QREQUEUEPIWAIT -> QREQUEUEPILOCKED rcuwaitwaitevent() if (atomicread(&q->requeuestate) != QREQUEUEPIWAIT) break / no schedule() /
/ q.pistate->owner == current / futexprivatehashput() / return from syscall / rcuwaitwakeup(&q->requeuewait) / q is gone /
futexrequeuepicomplete() publishes QREQUEUEPILOCKED before calling rcuwaitwakeup(). The waiter observes this state in rcuwaitwaitevent() before invoking schedule() in rcuwaitwaitevent(). Here, the waiter is free leave the syscall before requeue task can complete the wake.
To address this race skip rcuwaitwakeup() in the QREQUEUEPILOCKED case. This state is only published by requeuepiwakefutex(), which saves q->task before futexrequeuepicomplete() and wakes the waiter via wakeupstate().
This wake is intended to wake the waiter from its futexdowait() sleep. If the waiter is still sleeping there, it can not get into the QREQUEUEPIWAIT state (and require this removed wake). Should the waiter be woken up from futexdowait() by other means (as in this example) and sleep in futexrequeuepiwakeupsync() then the wakeupstate() from requeuepiwakefutex() will wake it, too. Should the waiter task terminate before wakeupstate() had a chance to wake the task then the task pointer does not become invalid because the futexhashbucket::lock is held and the task pointer is RCU protected.
[bigeasy: Updated comment and commit message]
Event History
Frequently Asked Questions
Which systems are exposed to this race?
The issue is described on Linux kernels configured with PREEMPT_RT. It involves priority-inheritance futex requeue handling through FUTEX_CMP_REQUEUE_PI.
What conditions are needed to trigger the vulnerability?
A waiting task must be woken early, such as by a timeout or signal, while another task is performing a PI futex requeue. The race can cause the requeue path to call rcuwait_wake_up() after the waiter's stack-allocated futex_q has gone out of scope.
How can administrators identify a suspected occurrence?
On affected PREEMPT_RT systems, the described symptom is a KASAN slab-out-of-bounds report in futex_requeue_pi_complete() during rcuwait_wake_up().
What should be done if the system uses this futex operation?
Apply the available kernel fix from the referenced stable commits. The fix prevents publication of the requeue state from allowing the waiter to return before the requeue-side wake-up handling is complete.