Cloudanix VulnDB

CVE-2026-46274

High · 7.8

CVSS

7.8

EPSS

0.1%

Published

Jun 8, 2026

CISA due date

—

Cloudanix analysis

Next patch cycle SSVC: Track

A local user or compromised application may be able to abuse a Linux kernel bug to take over the machine or crash it.

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

What it actually does

This is a Linux kernel use-after-free flaw in the io_uring io-wq worker queue. A local low-privileged user can manipulate queued io_uring work so that a non-hashed request is incorrectly recorded as the tail of a hashed work bucket. After that request completes and is freed, the per-task io_wq structure can retain a dangling pointer. A later enqueue operation can dereference that stale pointer and write through freed kernel memory, potentially causing kernel memory corruption, privilege escalation, information disclosure, or a kernel crash.

Why it matters to the business

Systems that allow local users, containers, sandboxed workloads, or exposed application runtimes to use io_uring may be at risk of local privilege escalation or denial of service. Although EPSS is currently very low, the flaw has high confidentiality, integrity, and availability impact once an attacker has local code execution. It is not currently listed in CISA KEV and no ransomware use is indicated, so remediation should be prioritized based on exposure to untrusted local workloads rather than internet exposure alone.

How an attack unfolds

An attacker first obtains the ability to run code as an unprivileged local user or within a workload that can access io_uring. They then create io_uring activity that arranges specific hashed and non-hashed io-wq work items in the same task-owned worker queue. By cancelling a hashed bucket-0 work item when a non-hashed work item is immediately before it, the vulnerable kernel can incorrectly store a pointer to the non-hashed request in hash_tail[0]. When the non-hashed request later completes, that request object is freed, but the stale hash_tail pointer remains in the per-task io_wq. The attacker then submits another hashed bucket-0 work item, causing the kernel to dereference the dangling pointer and write into freed memory. Depending on kernel configuration, allocator state, hardening features, and exploit reliability, this may result in a kernel panic or be shaped into a local privilege-escalation primitive.

How to fix it

Upgrade to a Linux kernel version or vendor-maintained kernel package that includes the fix adding the missing hashed-work validation in io_wq_remove_pending(). Because affected product and fixed-version data was not provided, use the relevant distribution or appliance vendor advisory to identify the exact patched kernel build. Where immediate patching is not possible, reduce exposure by restricting untrusted local shell access, minimizing multi-tenant workloads on affected kernels, using container isolation controls, and disabling or limiting io_uring where supported by the distribution or runtime. Reboot into the patched kernel after installation; merely installing a kernel package is not sufficient if the host continues running the old kernel.

How to confirm the fix worked

Confirm that the running kernel, not only the installed package, is a fixed vendor build. Validate with uname -r, package-manager kernel version checks, and the applicable distribution advisory. For source-based kernels, confirm that io_wq_remove_pending() checks whether the predecessor work item is hashed before updating hash_tail, specifically by using an io_wq_is_hashed()-style guard. After remediation, reboot and verify that the active kernel matches the patched version. Security teams should also confirm whether io_uring is available to untrusted users or containers and whether any temporary restrictions remain in effect until all systems are patched.

Typical attack path

  1. Gain local code execution as an unprivileged user, container process, or application user on a vulnerable Linux system.
  2. Open and use io_uring so the task has an associated io_wq worker queue.
  3. Queue a mixture of hashed and non-hashed io-wq work items with controlled ordering.
  4. Cancel a hashed bucket-0 work item whose predecessor is non-hashed, causing hash_tail[0] to point to the wrong request object.
  5. Allow the non-hashed request to complete and be freed while the stale pointer remains in the per-task io_wq.
  6. Submit another hashed bucket-0 work item so the kernel writes through the dangling pointer.
  7. Attempt to convert the resulting kernel memory corruption into privilege escalation, data exposure, or a system crash.

How to detect it

Detection should focus on evidence of attempted kernel memory corruption and local privilege-escalation activity, because successful exploitation may not leave a clean application-level audit trail. Review dmesg, journald, /var/log/kern.log, /var/log/messages, crash dumps, kdump output, KASAN/KFENCE reports, auditd events, EDR telemetry, and container runtime logs. Look for kernel oopses, panics, page faults, use-after-free reports, or general protection faults with stack traces mentioning io_uring, io-wq, io_wq_remove_pending, io_wq_insert_work, io_get_next_work, or wq_list_add_after. Correlate these events with local user activity, container starts, short-lived processes, privilege changes, setuid execution, suspicious new root-owned files, unexpected kernel crashes, or exploitation of an initial remote vulnerability. In hardened test or staging environments, enable kernel memory debugging where feasible to improve signal, but do not rely on crash artifacts alone because a successful privilege escalation may avoid an obvious panic.

  • io_wq_remove_pending
  • io_wq_insert_work
  • wq_list_add_after
  • io_get_next_work
  • io_uring
  • io-wq
  • hash_tail
  • KASAN: use-after-free
  • BUG: KASAN: use-after-free
  • general protection fault
  • kernel BUG at
  • Oops:
  • RIP: 0010:io_wq_insert_work
  • RIP: 0010:wq_list_add_after
  • RIP: 0010:io_wq_remove_pending
  • BUG: unable to handle page fault
  • slab-use-after-free
  • req_cachep

What your security team should do

  • Prioritize patching Linux systems that host untrusted local users, CI/CD runners, shared developer hosts, container platforms, sandboxed workloads, or internet-facing applications that could be exploited first for local code execution.
  • Inventory running kernel versions and map them to vendor advisories for this flaw; ensure systems are rebooted into the patched kernel.
  • If patching is delayed, consider disabling or restricting io_uring where operationally feasible and supported, especially on multi-tenant or high-risk hosts.
  • Review kernel logs for crashes, KASAN reports, or general protection faults involving io_uring, io-wq, io_wq_remove_pending, io_wq_insert_work, or wq_list_add_after.
  • Monitor for suspicious local exploitation chains, such as web service compromise followed by unusual io_uring-heavy processes, kernel crashes, or unexpected privilege changes.
  • Because there is no current KEV listing, no known ransomware association, and low EPSS, treat this as a high-impact local privilege-escalation risk rather than an active mass-exploitation emergency unless threat intelligence changes.

The record

In the Linux kernel, the following vulnerability has been resolved: io-wq: check that the predecessor is hashed in io_wq_remove_pending() io_wq_remove_pending() needs to fix up wq->hash_tail[] if the cancelled work was the tail of its hash bucket. When doing this, it checks whether the preceding entry in acct->work_list has the same hash value, but never checks that the predecessor is hashed at all. io_get_work_hash() is simply atomic_read(&work->flags) >> IO_WQ_HASH_SHIFT, and the hash bits are never set for non-hashed work, so it returns 0. Thus, when a hashed bucket-0 work is cancelled while a non-hashed work is its list predecessor, the check spuriously passes and a pointer to the non-hashed io_kiocb is stored in wq->hash_tail[0]. Because non-hashed work is dequeued via the fast path in io_get_next_work(), which never touches hash_tail[], the stale pointer is never cleared. Therefore, after the non-hashed io_kiocb completes and is freed back to req_cachep, wq->hash_tail[0] is a dangling pointer. The io_wq is per-task (tctx->io_wq) and survives ring open/close, so the dangling pointer persists for the lifetime of the task; the next hashed bucket-0 enqueue dereferences it in io_wq_insert_work() and wq_list_add_after() writes through freed memory. Add the missing io_wq_is_hashed() check so a non-hashed predecessor never inherits a hash_tail[] slot.

Affected packages

Ecosystem Package Introduced Fixed
openSUSE:Tumbleweed kernel-source 0 7.0.12-1.1

Related vulnerabilities