Linux 6.15 io_uring ZCRX freelist lacks bounds checking, enabling a 4-byte OOB slab write exploitable for local privilege escalation to root.
Key Takeaways
The bug: two teardown paths (ptr_ring drain + scrub loop) both push niovs to freelist[] without an upper bound on free_count, writing freelist[num_niovs] out-of-bounds.
Attacker controls the OOB write value (niov index, 0 to N-1) and target slab cache by choosing area_len at IFQ registration, giving three degrees of freedom from one syscall argument.
Exploit chain: corrupt msg_msg.m_list.next low 4 bytes, spray kmalloc-128 to land a fake header, over-read heap via msgrcv MSG_COPY, break KASLR, overwrite modprobe_path for uid=0 execution.
Affected: Linux 6.15-6.19 with CONFIG_IO_URING_ZCRX=y, a real ZCRX NIC (mlx5/ice/nfp), and CAP_NET_ADMIN. Fix is commit 770594e, not yet in any stable branch at time of writing.
KASLR bypass tries /proc/kallsyms first, then dmesg, then the msgrcv heap over-read scanning for kernel text pointers in range 0xffffffff80000000-0xfffffffffe000000.
Hacker News Comment Review
The CAP_NET_ADMIN + CAP_SYS_ADMIN requirement sounds restrictive, but commenters noted unprivileged user namespaces (enabled by default on most distros) grant both caps inside the namespace, making this a realistic LPE from any unprivileged user.
There is debate about whether this is already patched in stable; Jens Axboe reportedly commented the fix is in stable, but the write-up states otherwise – the discrepancy is unresolved in the thread.
io_uring’s track record prompted calls to disable it outright, especially in containers; commenters flagged it as a persistent source of syscall-smuggling primitives and LPEs, with this being the fourth Linux LPE in roughly ten days.
Notable Comments
@PlasmaPower: Unprivileged user namespaces hand out both CAP_NET_ADMIN and CAP_SYS_ADMIN by default on almost all distros, collapsing the apparent privilege bar.
@staticassertion: “io-uring is a security nightmare” – recommends disabling it outright; already off in most container runtimes.