Description
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.
Published: 2026-06-08
Score: n/a
EPSS: n/a
KEV: No
Impact: n/a
Action: n/a
AI Analysis

Impact

The flaw is in the Linux kernel’s io_wq_remove_pending routine, where the code fails to validate that a predecessor work item is hashed before reusing hash_tail pointers. When a hashed work entry is cancelled while an un-hashed predecessor is present, a stale pointer to freed memory is stored in wq->hash_tail[0]. Because the fast path for non-hashed work never clears this pointer, it becomes a dangling reference that may later be dereferenced by io_wq_insert_work, leading to kernel memory corruption. The likely attack vector is a local process that can orchestrate the specific sequence of IO cancellations and enqueues required to trigger the dangling pointer logic, potentially causing a denial of service or kernel fault. The weakness maps to CWE-416: Use-After-Free.

Affected Systems

All Linux kernel installations that predate the patch commit 252c5051 are potentially affected. This includes mainstream distributions running kernel 5.15.x, 6.1.x, 6.2.x and earlier releases, where the io_wq subsystem remains unpatched.

Risk and Exploitability

The CVSS score is unavailable and EPSS data is not provided, but kernel use-after-free defects typically carry high severity due to the possibility of memory corruption. No public exploits are listed in CISA KEV, and no known active exploits have been reported. However, an attacker with local access that can influence IO scheduling could exploit the defect to crash the system or, in some scenarios, elevate privileges.

Generated by OpenCVE AI on June 8, 2026 at 16:53 UTC.

Remediation

No vendor fix or workaround currently provided.

OpenCVE Recommended Actions

  • Apply a kernel update that includes commit 252c5051 or any later stable release containing the fix.
  • Reboot the system to load the patched kernel.
  • If a kernel upgrade cannot be performed immediately, restrict the use of the affected IO work queue functionality in applications or apply system controls to limit scheduled IO operations that could trigger the fault.

Generated by OpenCVE AI on June 8, 2026 at 16:53 UTC.

Tracking

Sign in to view the affected projects.

Advisories

No advisories yet.

History

Mon, 08 Jun 2026 15:45:00 +0000

Type Values Removed Values Added
Description 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.
Title io-wq: check that the predecessor is hashed in io_wq_remove_pending()
First Time appeared Linux
Linux linux Kernel
CPEs cpe:2.3:o:linux:linux_kernel:*:*:*:*:*:*:*:*
Vendors & Products Linux
Linux linux Kernel
References

Subscriptions

Linux Linux Kernel
cve-icon MITRE

Status: PUBLISHED

Assigner: Linux

Published:

Updated: 2026-06-08T14:30:53.323Z

Reserved: 2026-05-13T15:03:33.109Z

Link: CVE-2026-46274

cve-icon Vulnrichment

No data.

cve-icon NVD

Status : Received

Published: 2026-06-08T16:16:40.707

Modified: 2026-06-08T16:16:40.707

Link: CVE-2026-46274

cve-icon Redhat

No data.

cve-icon OpenCVE Enrichment

Updated: 2026-06-08T17:45:16Z

Weaknesses

No weakness.