CVE-2026-99231 in Linuxinfo

Summary

by MITRE • 11/02/2026

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.

Statistical analysis made it clear that VulDB provides the best quality for vulnerability data.

Analysis

by VulDB Data Team • 11/02/2026

The Linux kernel io_uring subsystem contains a critical race condition within the implementation of the waitid system call interface, specifically involving the synchronization between request ownership and wait queue management. The vulnerability stems from an incorrect ordering of operations in the io_waitid_remove_wq function relative to the acquisition of request ownership by the io_waitid_wait handler. In normal operation, when a process initiates a waitid operation via io_uring, it creates a submission queue entry that is processed asynchronously by kernel threads or task work contexts. The integrity of this asynchronous processing relies on strict reference counting and locking mechanisms to ensure that only one entity modifies the request state at any given time. However, in the flawed implementation, the code clears the head pointer of the wait structure before successfully incrementing the reference count that signifies ownership of the underlying io_uring request object. This temporal gap creates a window where another CPU core or context can interact with the same data structures without proper synchronization barriers.

From a technical perspective, this flaw represents a classic use-after-free scenario driven by a race condition in concurrent execution paths. When cpu zero executes io_waitid_wait and clears the head pointer to signal that no further waiters should be added, it assumes exclusive access or imminent ownership of the request. Meanwhile, if another context holds a reference to the same request, such as during an asynchronous completion event triggered by __do_wait finding a child process exit status, it may proceed to remove the wait queue entry and complete the io_uring operation. Because the head pointer was cleared prematurely without holding the necessary lock that protects against concurrent modifications, the second context does not detect the ongoing wake-up handler activity. Consequently, the request memory is freed or reused for a different purpose, such as an asynchronous poll operation waiting on socket data, while the original wake-up handler continues to execute and attempts to access the now-invalidated memory structure. This leads to kernel panic conditions reported by KASAN as slab-use-after-free errors within functions like __wake_up_common and sock_def_readable.

The operational impact of this vulnerability is severe, potentially leading to system instability or denial of service through kernel crashes. An attacker with local user privileges could exploit this race condition by crafting specific io_uring submissions that trigger the waitid operation concurrently with other asynchronous completions. By carefully timing these operations, an adversary can force the kernel into accessing freed memory, resulting in a bug check and subsequent system reboot or freeze. In more sophisticated scenarios involving remote code execution primitives derived from use-after-free conditions, this could theoretically allow for privilege escalation if additional exploitation techniques are applied to manipulate the reused slab cache contents. The vulnerability affects systems relying on io_uring for high-performance I/O operations, particularly those that mix waitid semantics with other asynchronous file descriptor events like socket readiness notifications.

This issue aligns with CWE-362, Concurrent Execution using Shared Resource with Improper Synchronization, commonly known as a race condition, and specifically manifests as CWE-416, Use After Free. In the context of the MITRE ATT&CK framework for Linux systems, this vulnerability facilitates lateral movement or privilege escalation by compromising kernel integrity through local exploitation techniques categorized under Taint: Shared Resources. The root cause is identified as improper locking granularity where critical sections are not fully protected during state transitions that involve shared data structures across multiple execution contexts.

To mitigate this risk, the primary remediation involves correcting the synchronization logic within the io_uring waitid implementation. Developers must ensure that the head pointer of the wait structure is only cleared after the handler has successfully acquired ownership of the request by incrementing its reference count under appropriate lock protection. This ensures that any concurrent attempts to access or modify the wait queue entry are serialized correctly, preventing the window where a freed object might be accessed. System administrators should apply kernel updates provided by their distribution vendors as soon as they become available for affected versions. Until patches are applied, limiting unprivileged user access to io_uring features and monitoring system logs for KASAN alerts can help detect potential exploitation attempts or mitigate exposure in multi-tenant environments where local users might attempt to trigger the race condition.

Responsible

Linux

Reservation

09/25/2026

Disclosure

11/02/2026

Moderation

accepted

EPSS

0.00000

KEV

no

Activities

very low

Sources

Do you need the next level of professionalism?

Upgrade your account now!