Cloudanix VulnDB

CVE-2026-80775

None

CVSS

—

EPSS

0.2%

Published

Sep 4, 2026

CISA due date

—

Cloudanix analysis

Schedule a fix SSVC: Track

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

  1. Create nested vfork hierarchy so parent and grandchild share an mm without having allocated the default futex hash
  2. Kill the vfork grandchild with SIGKILL to release the parent from vfork wait
  3. Have multiple tasks call prctl(PR_FUTEX_HASH, PR_FUTEX_HASH_SET_SLOTS) concurrently
  4. 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