Skip to main content

Linux Kernel EUVDEUVD-2026-35078

| CVE-2026-46274 HIGH
Use After Free (CWE-416)
2026-06-08 Linux GHSA-52w9-98q8-6pwf
7.8
CVSS 3.1 · Vendor: Linux
Share

Severity by source

Vendor (Linux) PRIMARY
7.8 HIGH
AV:L/AC:L/PR:L/UI:N/S:U/C:H/I:H/A:H
vuln.today AI
7.0 HIGH

Local io_uring access requires PR:L; winning the cancel/free/realloc race against per-task io_wq raises AC to H; successful UAF yields full kernel C/I/A compromise.

3.1 AV:L/AC:H/PR:L/UI:N/S:U/C:H/I:H/A:H
4.0 AV:L/AC:H/AT:N/PR:L/UI:N/VC:H/VI:H/VA:H/SC:N/SI:N/SA:N
SUSE
5.5 MEDIUM
AV:L/AC:L/PR:L/UI:N/S:U/C:N/I:N/A:H
Red Hat
7.8 MEDIUM
qualitative

Primary rating from Vendor (Linux).

CVSS VectorVendor: Linux

CVSS:3.1/AV:L/AC:L/PR:L/UI:N/S:U/C:H/I:H/A:H
Attack Vector
Local
Attack Complexity
Low
Privileges Required
Low
User Interaction
None
Scope
Unchanged
Confidentiality
High
Integrity
High
Availability
High

Lifecycle Timeline

5
Analysis Generated
Jun 14, 2026 - 06:23 vuln.today
CVSS changed
Jun 14, 2026 - 06:22 NVD
7.8 (HIGH)
Patch available
Jun 08, 2026 - 17:01 EUVD
CVE Published
Jun 08, 2026 - 14:30 nvd
UNKNOWN (no severity yet)
CVE Published
Jun 08, 2026 - 14:30 cve.org
HIGH 7.8

DescriptionCVE.org

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.

AnalysisAI

Local privilege escalation via use-after-free in the Linux kernel io_uring io-wq worker subsystem allows an unprivileged local user to corrupt kernel memory and potentially execute arbitrary code in kernel context. The flaw lives in io_wq_remove_pending(), where a missing io_wq_is_hashed() check on the predecessor work item lets a non-hashed io_kiocb be recorded in wq->hash_tail[0]; after that request is freed back to req_cachep, the stale pointer is dereferenced on the next hashed bucket-0 enqueue. EPSS is very low (0.02%) and no public exploit identified at time of analysis, but the bug is reachable from any process that can issue io_uring syscalls.

Technical ContextAI

The affected component is io-wq, the per-task worker pool used by io_uring to execute requests that must be punted out of the submission path (e.g., requests that would block). io-wq tracks hashed work - typically buffered writes to the same inode that must be serialized - in per-bucket hash_tail[] pointers, and uses io_get_work_hash() (atomic_read(&work->flags) >> IO_WQ_HASH_SHIFT) to read the hash value. Because non-hashed work has zero in the hash bits, io_get_work_hash() returns 0 for it, colliding with hash bucket 0; io_wq_remove_pending() compared hash values without first calling io_wq_is_hashed() on the predecessor, allowing a non-hashed io_kiocb pointer to be stored as the bucket-0 tail. The io_kiocb is then freed via the non-hashed fast path in io_get_next_work(), leaving a dangling pointer in a tctx-scoped io_wq that survives ring open/close, so io_wq_insert_work() / wq_list_add_after() later writes through freed memory - a classic CWE-416 use-after-free in a slab-allocated request object.

RemediationAI

Vendor-released patch: upgrade to mainline 7.1-rc4 or to a stable kernel containing the backport - specifically 6.6.141, 6.12.91, 7.0.10, or 6.18.33 - and rebuild distro kernels accordingly, then reboot affected hosts. The fix commits are published at https://git.kernel.org/stable/c/d6bda9df0c0a3080804181464d5c0f4d78a4e769, https://git.kernel.org/stable/c/d376c131af7c7739a87ff037ed2fdb67c2542c8a, https://git.kernel.org/stable/c/d6a2d7b04b5a093021a7a0e2e69e9d5237dfa8cc, https://git.kernel.org/stable/c/5a20ebf0c81b61f5ea3b1b529c100cad69b9f603, and https://git.kernel.org/stable/c/252c5051dba9c709b6a72f2866f93e5e618b3f06, and amount to adding an io_wq_is_hashed() check before the hash comparison in io_wq_remove_pending(). If patching must be deferred, disable unprivileged access to io_uring by setting kernel.io_uring_disabled=2 via sysctl (blocks all io_uring use; will break applications that rely on it such as recent QEMU, RocksDB, and some container runtimes), or kernel.io_uring_disabled=1 to gate it behind the io_uring_group capability (less disruptive but requires per-app rollout). On systems where io_uring is not required, building or booting a kernel without CONFIG_IO_URING removes the attack surface entirely at the cost of losing the API for any future workload.

Vendor StatusVendor

SUSE

Severity: Moderate
Product Status
openSUSE Tumbleweed Fixed
SUSE Linux Enterprise Desktop 15 SP7 Not-Affected
SUSE Linux Enterprise Desktop 15 SP7 Not-Affected
SUSE Linux Enterprise High Availability Extension 15 SP7 Not-Affected
SUSE Linux Enterprise High Availability Extension 15 SP7 Not-Affected

Share

EUVD-2026-35078 vulnerability details – vuln.today

This site uses cookies essential for authentication and security. No tracking or analytics cookies are used. Privacy Policy