Cloudanix VulnDB

CVE-2026-99231

High · 7.8

CVSS

7.8

EPSS

0.1%

Published

Nov 2, 2026

CISA due date

—

Cloudanix analysis

Schedule a fix SSVC: Track

A timing flaw in the Linux kernel can let a local program corrupt memory and potentially take over the system or crash it.

Exploitation
Local Privilege
Attacker needs
Low Privilege
Complexity
Low
Impact
Full Compromise
Component
OS kernel
Class
Use After Free
Remediation
Upgrade
Effort
Medium
Patch risk
Medium

What it actually does

Race condition in io_uring waitid handling allows ->head to be cleared before the request is owned via refcount bump, enabling concurrent completion and reuse that leads to slab use-after-free on subsequent wakeups.

Why it matters to the business

Local attackers on affected Linux systems can trigger kernel memory corruption, resulting in crashes, denial of service, or potential privilege escalation; recent publication increases urgency for patching in environments relying on io_uring.

How an attack unfolds

An attacker issues io_uring waitid operations while racing with child process events or cancellations; by delaying refcount acquisition after ->head is nulled, the request is completed and reused for another operation such as a socket receive, causing the wakeup handler to touch freed memory.

How to fix it

Update the Linux kernel to a version containing the fix that ensures ->head is cleared only after the handler owns the request via refcount; rebuild and reboot systems using affected kernels.

How to confirm the fix worked

Verify kernel source contains the commit ensuring ownership before clearing ->head; run targeted io_uring waitid stress tests under KASAN or confirm absence of the described slab-use-after-free report.

Typical attack path

  1. Submit io_uring waitid SQE
  2. Trigger concurrent child event or cancellation path
  3. Exploit timing window to clear ->head before ref bump
  4. Force request completion and reuse for another opcode
  5. Induce wakeup that dereferences freed request state

How to detect it

Search kernel logs for KASAN slab-use-after-free reports mentioning __wake_up_common, io_waitid, or sock_def_readable; inspect io_uring task work and request reuse patterns around the time of crashes.

  • BUG: KASAN: slab-use-after-free in __wake_up_common
  • io_waitid_remove_wq
  • io_arm_apoll
  • __io_submit_flush_completions

What your security team should do

  • Prioritize kernel updates on all systems exposing io_uring to untrusted users
  • Restrict io_uring usage via seccomp or LSM policies where feasible until patched
  • Monitor for related kernel oops or KASAN reports in production workloads

The record

In the Linux kernel, the following vulnerability has been resolved: io_uring/waitid: own the request before clearing ->head io_waitid_remove_wq() only takes the wait queue lock if ->head is set. io_waitid_wait() clears ->head first thing, before it tries to become the owner of the request by bumping ->refs. If somebody else owns the request at that point, nothing keeps it from completing the request while the wake up handler is still going to touch it: CPU0 (io_waitid_wait) CPU1 (io_waitid, holds a ref) list_del_init(&wait->entry) smp_store_release(&iw->head, NULL) __do_wait() finds another child io_waitid_remove_wq() // ->head == NULL, no locking io_waitid_finish(), IOU_COMPLETE // request freed and reused atomic_fetch_inc(&iw->refs) The same goes for __io_waitid_cancel() if it claims the request in that window. ->refs is part of the per opcode data of the request, so this increments whatever the next user of the request keeps there. If that happens to be zero, the handler concludes that it owns the request, and queues io_waitid_cb() for it. With the window held open by a delay, and the request reused for a receive that is waiting for data: BUG: KASAN: slab-use-after-free in __wake_up_common+0x1ca/0x1f0 __wake_up_sync_key+0x36/0x50 sock_def_readable+0xf1/0x420 unix_stream_sendmsg+0x60b/0x1110 Allocated by task 87: io_arm_apoll+0x1ed/0x940 Freed by task 87: __io_submit_flush_completions+0x118d/0x1a10 tctx_task_work_run+0x327/0x950 Only clear ->head once the handler owns the request. If it doesn't, the owner finds ->head set and has to wait for the lock, which is held by the caller of the handler. Deleting the already deleted entry again is harmless.

Affected packages

Ecosystem Package Introduced Fixed