Skip to content

An unvalidated futex waiter can consume wake(1) while a validated waiter remains blocked #1267

Description

@CvvT

One subtle issue found by Specula:

FutexManager::wait inserts a waiter into the futex bucket before it validates that the futex word still equals the expected value. FutexManager::wake(count=1) scans and counts matching queue entries without knowing whether a selected waiter has passed that validation. As a result, an unvalidated waiter can consume the single wake quota, return ImmediatelyWokenBecauseValueMismatch, and leave a validated waiter blocked.

See the full report for more details.

According to copilot, Linux uses a two-stage approach:

  1. Under the bucket lock, perform a no-fault read.
  2. If it faults, release the lock.
  3. Perform a normal fault-capable read to bring the page in.
  4. Reacquire the lock and repeat the comparison.
  5. Enqueue only while still holding that lock.

LiteBox currently inserts and then checks without holding the list lock across both operations, which avoids missed wakes but introduces the wake-consumption race we identified. LoanList already has a per-bucket mutex; its API just does not expose atomic check-and-insert. A robust LiteBox fix likely needs a distinct read_no_fault() operation. Using the existing read_at_offset() under the LoanList lock requires guaranteeing that it cannot block or re-enter lock-dependent code.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Labels

No labels
No labels

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions