Skip to content

Reject unaligned futex uaddr#17

Merged
jserv merged 1 commit intomainfrom
futex
May 7, 2026
Merged

Reject unaligned futex uaddr#17
jserv merged 1 commit intomainfrom
futex

Conversation

@jserv
Copy link
Copy Markdown
Contributor

@jserv jserv commented May 7, 2026

Linux's unaligned_p() rejects futex operations whose uaddr is not 4-byte aligned, since an unaligned 4-byte word loses atomicity on arm64 and can straddle a page boundary. Mirror that across the
WAIT/WAKE/REQUEUE/CMP_REQUEUE/WAKE_OP/LOCK_PI/TRYLOCK_PI/UNLOCK_PI dispatch sites by returning -EINVAL when the uaddr fails the 4-byte alignment check.

robust_list_walk now applies the same check before touching each futex word: an unaligned or out-of-range futex_gva is skipped (the list itself still advances). Without the gate, a partial cross-page guest_write_small could leave the futex word in a torn state while the subsequent wake is suppressed, leaving waiters wedged on a half-modified word.

Also handle the OWNER_DIED write failure case: log the address at debug level and suppress the wake. Waking after a failed write would just send waiters back to sleep on the unchanged word. This mirrors Linux handle_futex_death, which gives up on the entry without waking when the user-memory update faults. log_debug avoids stderr spam when a corrupted robust list trips the cap repeatedly.


Summary by cubic

Reject unaligned futex addresses across all futex paths and tighten robust-list cleanup to avoid torn writes and stuck waiters. Matches Linux by returning -EINVAL for any 4-byte misaligned uaddr and by suppressing wakeups when OWNER_DIED updates fail.

  • Bug Fixes
    • Return -EINVAL for misaligned uaddr in WAIT, WAKE, REQUEUE/CMP_REQUEUE, WAKE_OP, and PI ops (LOCK_PI, TRYLOCK_PI, UNLOCK_PI).
    • In robust_list_walk, skip out-of-range or unaligned futex words; on OWNER_DIED write failure, log debug with address and do not wake.
    • Add tests verifying -EINVAL on unaligned addresses for WAIT, WAKE, and PI ops.

Written for commit 16ad7b4. Summary will update on new commits.

Linux's unaligned_p() rejects futex operations whose uaddr is not 4-byte
aligned, since an unaligned 4-byte word loses atomicity on arm64 and can
straddle a page boundary. Mirror that across the
WAIT/WAKE/REQUEUE/CMP_REQUEUE/WAKE_OP/LOCK_PI/TRYLOCK_PI/UNLOCK_PI
dispatch sites by returning -EINVAL when the uaddr fails the 4-byte
alignment check.

robust_list_walk now applies the same check before touching each futex
word: an unaligned or out-of-range futex_gva is skipped (the list itself
still advances). Without the gate, a partial cross-page guest_write_small
could leave the futex word in a torn state while the subsequent wake is
suppressed, leaving waiters wedged on a half-modified word.

Also handle the OWNER_DIED write failure case: log the address at debug
level and suppress the wake. Waking after a failed write would just send
waiters back to sleep on the unchanged word. This mirrors Linux
handle_futex_death, which gives up on the entry without waking when the
user-memory update faults. log_debug avoids stderr spam when a corrupted
robust list trips the cap repeatedly.
Copy link
Copy Markdown

@cubic-dev-ai cubic-dev-ai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No issues found across 2 files

@jserv jserv merged commit be4321e into main May 7, 2026
5 checks passed
@jserv jserv deleted the futex branch May 7, 2026 18:02
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant