In the Linux kernel, the following vulnerability has been resolved:
io-wq: check that the predecessor is hashed in iowqremove_pending()
iowqremovepending() needs to fix up wq->hashtail[] if the cancelled work was the tail of its hash bucket. When doing this, it checks whether the preceding entry in acct->worklist has the same hash value, but never checks that the predecessor is hashed at all. iogetworkhash() is simply atomicread(&work->flags) >> IOWQHASHSHIFT, 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 iokiocb is stored in wq->hashtail[0].
Because non-hashed work is dequeued via the fast path in iogetnextwork(), which never touches hashtail[], the stale pointer is never cleared. Therefore, after the non-hashed iokiocb completes and is freed back to reqcachep, wq->hashtail[0] is a dangling pointer. The iowq is per-task (tctx->iowq) 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 iowqinsertwork() and wqlistadd_after() writes through freed memory.
Add the missing iowqishashed() check so a non-hashed predecessor never inherits a hashtail[] slot.
{
"osv_generated_from": "https://github.com/CVEProject/cvelistV5/tree/main/cves/2026/46xxx/CVE-2026-46274.json",
"cna_assigner": "Linux"
}