A race in Linux's Unix domain socket code lets a local user break out of a container by peeking at queued messages without removing them: the same interaction has been patched three times since 2021.
A Linux kernel networking race lets an unprivileged local user break out of a container. The latest fix, CVE-2026-53361, patches the third version of the same bug in five years, and the fix changes where a single flag is set, not how the AF_UNIX garbage collector decides which sockets are dead.
AF_UNIX is the part of the kernel that handles Unix-domain sockets, the local-only channel programs use to hand file descriptors between processes. Inside it, a small garbage collector walks the socket graph and frees in-flight sockets that form unreachable reference cycles. A concurrent recvmsg() call with MSG_PEEK, the flag that lets a caller look at a queued message without removing it, is supposed to take a reference the collector counts. The collector is supposed to back off while a peek is in flight. The flag it checks, gc_in_progress, is one bit.
The race is that gc_in_progress is read lock-free, can read false mid-run, and lets a second unix_gc() worker slip through. The PoC repository from sgkdev walks through the sequence: a second scheduler tick passes the if (!gc_in_progress) guard, queues a second work item, and the second collector runs with the flag still false. A peek that arrives in that window takes a reference the second collector never sees, the socket is freed while the caller still holds it, and the kernel hands back a dangling sk_buff. SentinelOne's write-up classifies it as CWE-362, a race condition that wins when two paths share a single-flag handshake.
The NVD record lists four patch commits; the one that closes this race is d82ba05263c6, "af_unix: Set gc_in_progress to true in unix_gc()". The change is small. The flag was previously flipped before the worker was queued; the fix moves the flip inside the worker itself, so the second worker that slips through the guard can no longer run with the flag false.
That is the third time the same interaction has been patched. CVE-2021-0920 (commit cbcf01128d0a) was the 2021 fix for the GC-vs-MSG_PEEK race. CVE-2026-23394 (commit e5b31d988a41) was the fix a few months before this one. Each round has left the same design question open: the AF_UNIX garbage collector is reachable from any process that can open a Unix-domain socket, and it shares one boolean with a syscall that any unprivileged caller can issue. A reader who runs containers on a Linux host has been on this ride before.
Stable kernel 6.12 was vulnerable through 6.12.94; LWN's coverage of the same stable batch notes 6.12.95 closed an IPv6 container escape (CVE-2026-53362) and a KVM use-after-free (CVE-2026-53359) alongside kernel updates in this cycle, though it does not name CVE-2026-53361 explicitly. RHEL 10 ships 6.12 and is still exposed in this PoC's scope. Debian trixie, also on 6.12, shipped DSA-6381-1 with 6.12.94+deb13, which the PoC authors mark as patched. Ubuntu 24.04 HWE on 6.17 is vulnerable through 6.17.0-41 and hasn't yet shipped a fix. Ubuntu 24.04 GA on 6.8 is vulnerable but uses the non-MSG_PEEK path, so the published PoC doesn't target it. The PoC is also out of scope for 7.x kernels.
The PoC targets 2–7 CPUs and leaves the clean order-N strategy out of scope, because the authors didn't think exposing it for a -1 day bug was worth the trade. SLUB cache armoring, the per-cache defenses the kernel uses to make slab reuse unpredictable, is mostly stripped. The SID-leak phase, the part of the exploit that turns a use-after-free into a controlled object, can collide with low-order kmalloc-64 reuse, the kernel's 64-byte slab cache, or with anon_vma and per-cache PCP lists, the per-CPU page lists the allocator drains before going to the buddy system. Higher buckets and dedicated caches are safe. The lower buckets need extra armoring before reliability pushes toward 100%.
KASAN or kernel warnings from net/unix/garbage.c, or slab corruption on unix_sock and scm_fp_list, are the detection signature for a host that just ran an unprivileged container workload. The fix path is the boring one: vendor kernel updates. For hosts that can't update on the kernel cadence, the only durable mitigation is restricting which local users can open Unix-domain sockets inside a container, which isn't a control the kernel offers as a knob.
The watch item is the next commit in the same file. If the next fix in net/unix/garbage.c lands inside the collector's reference-counting path rather than around the flag, that is a sign the kernel is moving from one-bit handshakes to a real lock. If it lands around the flag again, the same design is still doing the work.