Логотип exploitDog
Консоль
Логотип exploitDog

exploitDog

redhat логотип

CVE-2026-46274

Опубликовано: 08 июн. 2026
Источник: redhat
CVSS3: 7.8
EPSS Низкий

Описание

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.

A flaw was found in the Linux kernel's input/output work queue (io-wq) component. This vulnerability occurs because the system incorrectly handles work queue entries, leading to a stale pointer. A local attacker could exploit this issue by manipulating work queue operations. Successful exploitation could allow the attacker to write to freed memory, potentially leading to privilege escalation or a system crash (denial of service).

Отчет

An io-wq use-after-free can occur when io_wq_remove_pending updates hash_tail for a hashed bucket-0 work item using a predecessor that is not hashed. A non-hashed predecessor can then be dequeued without clearing hash_tail, later freed back to req_cachep, and the next hashed bucket-0 enqueue can write through the dangling pointer. For the CVSS the PR:L because a local user or local process with access to io_uring is needed to create and cancel the relevant work items. Impact is at least local denial of service via kernel crash and may allow privilege escalation because the primitive is a kernel use-after-free with a write through freed memory. For the Red Hat Enterprise Linux the related Kernel config param CONFIG_IO_WQ disabled, so the bug not actual ("not affected").

Меры по смягчению последствий

For the Red Hat Enterprise Linux the related Kernel config param CONFIG_IO_WQ disabled, so the bug not actual ("not affected").

Затронутые пакеты

ПлатформаПакетСостояниеРекомендацияРелиз
Red Hat Enterprise Linux 10kernelNot affected
Red Hat Enterprise Linux 6kernelNot affected
Red Hat Enterprise Linux 7kernelNot affected
Red Hat Enterprise Linux 7kernel-rtNot affected
Red Hat Enterprise Linux 8kernelNot affected
Red Hat Enterprise Linux 8kernel-rtNot affected
Red Hat Enterprise Linux 9kernelNot affected
Red Hat Enterprise Linux 9kernel-rtNot affected

Показывать по

Дополнительная информация

Статус:

Moderate
Дефект:
CWE-825
https://bugzilla.redhat.com/show_bug.cgi?id=2486404kernel: io-wq: check that the predecessor is hashed in io_wq_remove_pending()

EPSS

Процентиль: 4%
0.00138
Низкий

7.8 High

CVSS3

Связанные уязвимости

CVSS3: 7.8
ubuntu
около 2 месяцев назад

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 ...

CVSS3: 7.8
nvd
около 2 месяцев назад

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

CVSS3: 7.8
msrc
около 2 месяцев назад

io-wq: check that the predecessor is hashed in io_wq_remove_pending()

CVSS3: 7.8
debian
около 2 месяцев назад

In the Linux kernel, the following vulnerability has been resolved: i ...

CVSS3: 7.8
github
около 2 месяцев назад

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...

EPSS

Процентиль: 4%
0.00138
Низкий

7.8 High

CVSS3