Cloudanix VulnDB

CVE-2026-99228

None

CVSS

—

EPSS

0.2%

Published

Nov 2, 2026

CISA due date

—

Cloudanix analysis

Schedule a fix SSVC: Track

A Linux kernel bug can make some programs using fast input-output features freeze when they try to close, requiring a manual shutdown to recover.

Exploitation
Local Privilege
Attacker needs
Local User
Complexity
Moderate
Impact
Denial Of Service
Component
OS kernel
Class
Race Condition
Remediation
Upgrade
Effort
Medium
Patch risk
Low

What it actually does

A race in io_uring/io-wq allows TIF_NOTIFY_SIGNAL to be cleared by io_run_task_work before a bounded work item (such as fifo_open) is started under IO_WQ_BIT_EXIT, so the worker misses the wake from io_wq_worker_wake and blocks indefinitely in an interruptible wait.

Why it matters to the business

Applications or services that use io_uring for asynchronous file operations can hang on thread or process exit, forcing administrators to kill processes, leaking resources and disrupting availability until the system is rebooted or the offending task is terminated.

How an attack unfolds

A local attacker submits an async IORING_OP_OPENAT for a FIFO with no writer, then immediately exits the submitting thread; the exit path signals workers once, but the race lets a worker clear the signal before starting the bounded work, leaving the thread stuck in do_exit.

How to fix it

Apply the upstream kernel commit that sets TIF_NOTIFY_SIGNAL for bounded work started with IO_WQ_BIT_EXIT and uses clear_notify_signal as a barrier; rebuild and reboot with the patched kernel.

How to confirm the fix worked

Inspect io_wq.c for the added IO_WQ_BIT_EXIT handling and clear_notify_signal call before wait_for_completion_timeout; verify that io_assign_current_work no longer drops the signal for exit work items.

Typical attack path

  1. Create or open a FIFO with no writer end
  2. Submit IORING_OP_OPENAT via io_uring with IOSQE_ASYNC
  3. Exit the thread or process that owns the ring
  4. io_wq_exit_workers signals workers but the signal is lost
  5. Worker blocks forever in wait_for_partner inside fifo_open

How to detect it

Search kernel logs and process listings for threads stuck in do_exit with io_wq workers blocked on wait_for_completion_timeout or wait_for_partner after an io_uring open; correlate with recent io_uring ring submissions that target FIFOs.

What your security team should do

  • Prioritize kernel updates containing the io-wq exit fix
  • Temporarily restrict untrusted code from using io_uring open operations on FIFOs or named pipes
  • Monitor process exit paths for stuck io_uring workers in production workloads
  • Review any custom io_uring usage for similar bounded-work patterns

The record

In the Linux kernel, the following vulnerability has been resolved: io_uring/io-wq: don't lose the signal that ends work When a thread exits, only its tracked requests are cancelled. Then its io-wq is torn down. io_wq_exit_workers() signals every worker, to get it out of an interruptible sleep, and waits for all of them to exit. Before they do, they go through the work that is left. Unbounded work is cancelled. Bounded work is run, as it is expected to end by itself. Not all of it does. An open has no file yet, so it counts as bounded, and the open of a FIFO waits for the other end. That is what the signal is for. But the workers are signalled once, and a worker that hasn't started the work by then loses the signal: io_wq_exit_workers() io_worker_handle_work() io_wq_worker_wake() set TIF_NOTIFY_SIGNAL io_assign_current_work() io_run_task_work() clear TIF_NOTIFY_SIGNAL io_wq_submit_work() fifo_open() wait_for_partner() wait_for_completion_timeout() The thread never gets out of do_exit(): IORING_OP_OPENAT of a FIFO without a writer, IOSQE_ASYNC exit of the thread that has submitted it hangs in more than 9 of 10 attempts (4 CPUs, KVM), until the process is killed. Set TIF_NOTIFY_SIGNAL for bounded work that is started with IO_WQ_BIT_EXIT set. The bit is set before the workers are signalled, and it is tested after the flag has been cleared, with clear_notify_signal() providing the barrier. So either the flag stays, or the bit is seen. Work that is started while the io-wq exits is treated like work that is being run at that time: it isn't interrupted unless it waits interruptibly.

Affected packages

Ecosystem Package Introduced Fixed