CVE-2026-80775
NoneCVSS
—
EPSS
0.2%
Published
Sep 4, 2026
CISA due date
—
Cloudanix analysis
A Linux kernel bug in process creation handling can cause memory errors that crash systems or open the door to attacks under certain multi-tasking conditions.
- Exploitation
- Local Privilege
- Attacker needs
- Local User
- Complexity
- Moderate
- Impact
- Privilege Gain
- Component
- OS kernel
- Class
- Race Condition
- Remediation
- Upgrade
- Effort
- Medium
- Patch risk
- Low
What it actually does
Race condition in futex_hash_allocate() permits concurrent stores to mm->futex.phash.ref without locking when nested vfork releases the parent; the last store wins, the first percpu counter becomes unreachable, its references are missed by __futex_ref_atomic_end(), the private hash is freed while still referenced, and futex_q_lock() writes into freed memory.
Why it matters to the business
Kernel memory corruption or crashes on Linux systems during specific multi-threaded and vfork workloads, risking denial of service and potential privilege escalation in high-concurrency environments.
How an attack unfolds
Attacker creates nested vfork calls so a grandchild can be killed with SIGKILL, releasing the parent to run concurrently with the grandchild in the same mm; both then issue prctl(PR_FUTEX_HASH, PR_FUTEX_HASH_SET_SLOTS) simultaneously to trigger the double-store and subsequent use-after-free during futex queue operations.
How to fix it
Apply the upstream fix that stores the percpu counter with cmpxchg() and takes the initial reference before the store; rebuild and deploy updated kernels containing this change.
How to confirm the fix worked
Confirm the kernel source contains the cmpxchg-based allocation in futex_hash_allocate(); run targeted concurrency tests exercising nested vfork plus PR_FUTEX_HASH calls and verify no use-after-free occurs.
Typical attack path
- Create nested vfork hierarchy so parent and grandchild share an mm without having allocated the default futex hash
- Kill the vfork grandchild with SIGKILL to release the parent from vfork wait
- Have multiple tasks call prctl(PR_FUTEX_HASH, PR_FUTEX_HASH_SET_SLOTS) concurrently
- Perform futex operations that acquire buckets from the now-freed private hash
How to detect it
Inspect kernel logs and crash dumps for oops, warnings, or slab-use-after-free reports originating from futex_q_lock() or __futex_ref_atomic_end(); correlate with processes performing vfork and prctl(PR_FUTEX_HASH) sequences.
What your security team should do
- Prioritize kernel updates containing the futex hash allocation fix across all Linux distributions
- Review workloads that rely on vfork or CLONE_VM for exposure
- Add kernel crash and oops monitoring for futex-related use-after-free signatures
- Test the race condition in staging environments before production rollout
The record
In the Linux kernel, the following vulnerability has been resolved: futex: Fix race on the initial mm->futex.phash.ref allocation futex_hash_allocate() allocates mm->futex.phash.ref without any locking. Commit d9b05321e21e ("futex: Move futex_hash_free() back to __mmput()") moved the allocation here and assumed that the process has just a single thread at this point. Commit ee9dce44362b ("futex: Drop CLONE_THREAD requirement for private default hash alloc") widened need_futex_hash_allocate_default() to cover any CLONE_VM clone, but left out vfork because the parent is suspended and cannot race. That no longer holds once vfork is nested. If a vfork child calls vfork again and is then killed with SIGKILL, the parent is released from its vfork wait and runs concurrently with the grandchild in the same mm. Neither of them went through futex_hash_allocate_default(). When both call prctl(PR_FUTEX_HASH, PR_FUTEX_HASH_SET_SLOTS) at the same time, each one sees mm->futex.phash.ref as NULL and stores its own percpu counter. Only the last store survives. The counter stored first is no longer reachable from the mm, so the references on it are not seen by __futex_ref_atomic_end(). A private hash that still has references is then considered dead and freed, and a task that still holds one of its buckets writes into freed memory in futex_q_lock(). Store the counter once with cmpxchg() and let the loser free_percpu() its own. The initial reference has to be taken before the store, otherwise another task can install a private hash while the counter is still 0.
Affected packages
| Ecosystem | Package | Introduced | Fixed |
|---|