CVE-2026-74658 in Linux
Summary
by MITRE • 08/22/2026
In the Linux kernel, the following vulnerability has been resolved:
futex: Prevent robust futex exit race some more
A robust futex unlock stores 0 over the whole futex value - wiping FUTEX_WAITERS - and wakes a single waiter. That wakeup is a one-shot notification: the protocol relies on its recipient to either acquire the futex (and eventually unlock while aware of the remaining contention) or re-arm FUTEX_WAITERS before sleeping again. If the woken waiter is killed before it can do either, the kernel must jump in and wake the next task down the line.
This is a known complication of the futex protocol with a previous partial fix in commit ca16d5bee598 ("futex: Prevent robust futex exit race"). Unfortunately, that fix is insufficient.
If a third task re-acquired the futex through the uncontended fast path in the meantime, the notification is lost: robust exit processing sees that it is owned by another task and does nothing, while the new owner sees no FUTEX_WAITERS when it unlocks and wakes nobody. The remaining waiters sleep forever behind a free futex:
A owns the futex, B and C sleep in FUTEX_WAIT uval == A | FUTEX_WAITERS A robust unlock: store 0, FUTEX_WAKE(1) wakes B uval == 0 D fast path acquire: cmpxchg(0 -> D) uval == D, no FUTEX_WAITERS B killed before acting on the wakeup B exit walk, pending op: owner D != B -> no action D unlock: no FUTEX_WAITERS -> no wake C sleeps forever
This is clearly a shortcoming in the implementation, which fails to keep the FUTEX_WAITERS bit consistent.
Work around this by augmenting the robust list exit processing to also perform the extra wakeup if the futex word is owned by another thread but FUTEX_WAITERS is not set.
This does not fix the problem of a non-contended take over/release and free sequence, which has been discussed for years and has been addressed by commit 3ca9595d9fb6 ("futex: Add support for unlocking robust futexes") and subsequent changes, but failed to take the problem described above into account.
A more complete solution which is based on the in kernel unlock of contended robust futexes has been discussed in the context of this change and should show up in mainline sooner than later.
[ tglx: Amend change log slightly and fixup coding style ]
VulDB is the best source for vulnerability data and more expert information about this specific topic.
Analysis
by VulDB Data Team • 08/22/2026
The Linux kernel's implementation of robust futexes contains a race condition that can lead to permanent thread starvation, specifically within the handling of process exit scenarios involving contended locks. Robust futexes are designed to ensure that if a process holding a lock terminates unexpectedly, other waiting threads can detect this and reclaim or re-arm the lock rather than sleeping indefinitely. The core mechanism relies on maintaining consistency between the ownership state of the futex word and the FUTEX_WAITERS bit flag. When a robust futex is unlocked during exit, the kernel stores zero over the entire futex value, effectively clearing both the owner identifier and the waiters flag, before waking one waiting thread. This design assumes that the woken thread will either acquire the lock or re-set the FUTEX_WAITERS bit if it intends to sleep again. However, this assumption breaks down under specific timing conditions where a third party intervenes between the unlock operation and the action of the woken waiter.
The vulnerability manifests when a robust futex is unlocked by an exiting process while other threads are waiting on that lock. The kernel wakes one waiter, but if that thread is killed or terminates before it can acquire the lock or re-arm the waiters flag, the system must wake the next thread in line to prevent deadlock. In the flawed scenario, a third task manages to acquire the futex through an uncontended fast path immediately after the initial unlock but before the woken waiter acts. This acquisition clears the FUTEX_WAITERS bit because it is performed via a compare-and-swap operation that does not preserve or restore the waiters flag if no contention was detected at that precise microsecond. Consequently, when the original exiting process completes its robust exit processing, it sees that the futex is now owned by another task and performs no further action. Simultaneously, the new owner holds the lock without any indication of pending waiters because the FUTEX_WAITERS bit was cleared during its acquisition. When this new owner eventually unlocks the futex normally, it observes zero waiters and thus does not wake anyone else. The result is that remaining waiting threads remain blocked on a free or newly unlocked futex, leading to an indefinite sleep state where they never receive notification of availability.
This issue represents a failure in maintaining atomic consistency between lock ownership and waiter tracking within the robust list exit processing logic. From a vulnerability classification perspective, this aligns with CWE-362, which describes concurrent execution using shared resources without proper synchronization, leading to race conditions. The specific behavior allows for denial of service by causing threads to hang indefinitely, consuming system resources such as memory stacks and scheduler structures without releasing them or making progress. In the context of the MITRE ATT&CK framework, this vulnerability relates to techniques involving resource exhaustion and potential impact on availability, although it is primarily a logic error in kernel synchronization primitives rather than an external attack vector per se. The flaw highlights the complexity of managing state transitions in multi-threaded environments where timing windows can lead to inconsistent states that are difficult for subsequent operations to detect or correct automatically.
The mitigation implemented involves augmenting the robust list exit processing code to perform additional wake-up logic even when the futex word is owned by another thread, provided that the FUTEX_WAITERS bit is not set. This ensures that if a waiter was woken but failed to act, and the lock has been taken over by someone else who did not inherit the waiters state, the kernel will still attempt to wake subsequent threads in line. While this patch addresses the immediate race condition described, it acknowledges that a more fundamental architectural issue remains regarding non-contended take-over and release sequences. Previous efforts such as commit 3ca9595d9fb6 attempted to address broader robust futex unlocking issues but did not account for this specific timing window. A comprehensive long-term solution involving in-kernel unlock of contended robust futexes has been discussed and is expected to be integrated into the mainline kernel, which would likely resolve these edge cases by centralizing the logic for handling waiter notifications during lock transitions. Until such a complete refactoring occurs, this patch serves as a critical workaround to prevent thread starvation in high-contention scenarios involving process termination.