ipv6_frag_escape: Linux LPE - Reliable Jail/Container Escape
Summary
Proof of concept for a Linux local privilege escalation and container/jail escape via an IPv6 fragmentation bug in the kernel, targeting CentOS/RHEL 10.
View Cached Full Text
Cached at: 06/29/26, 06:30 PM
sgkdev/ipv6_frag_escape
Source: https://github.com/sgkdev/ipv6_frag_escape
IPV6_FRAG_ESCAPE
A reliable unprivileged container / jail escape proof of concept for CentOS / RHEL 10.
It rides a now fixed IPv6 fragmentation bug in __ip6_append_data() (closed upstream by
38becddc, no CVE), an in-slab linear overflow into the skb_shared_info at the tail of a
packet’s own head object. This README documents the exploitation chain only. It does not
cover the trigger.
Scope
- Target: CentOS / RHEL 10 (kernel 6.12.x, e.g.
6.12.0-242.el10). - Start: an unprivileged process inside a network isolated container, with access to unprivileged user namespaces.
- Result: an interactive root shell in the host’s initial namespaces and root filesystem.
Notes
This is a proof of concept, deliberately not a turnkey weapon. The reliability scaffolding
is intentionally left out: no per-CPU PCP grooming, no cross-cache SLUB armoring, and the
skb head is placed in a shared, not so quiet cache. What ships fires often enough to
prove the chain, and not much more. It is scoped to CentOS / RHEL 10 only.
Requirements
CONFIG_INIT_ON_ALLOC_DEFAULT_ONoff, the RHEL / CentOS default. This PoC plants a stale pointer in uninitialised slab bytes; withinit_on_alloc=1that slot is zeroed and this particular technique only crashes the kernel (a NULL deref). That is a limit of the technique, not of the bug: a full exploit that also covers those kernels, with a different technique, will follow once the fix and CVE are public.- 5-level paging (LA57, 57-bit linear addresses). The page table walk is wired for five levels and a startup check refuses to run without it. A 4-level CPU would need the walk refactored.
/sys/kernel/btf/vmlinuxpresent and world readable (stock on RHEL / CentOS).
Tested kernels
| Distro | Kernel | Result |
|---|---|---|
| CentOS Stream 10 | 6.12.0-242.el10 | root, container escape |
| RHEL 10 | 6.12.0-228.el10 | httpd_t context escape |
Exploitation chain
-
In-slab overflow to a self-UAF. The bug yields control of the single
nr_fragsbyte inskb_shared_info. The free path (skb_release_data()) walksfrags[0 .. nr_frags)andput_page()s each entry, andfrags[]is never initialised. We pre-plant astruct page *for a pipe buffer page into that slab slot through controlled cache reuse, then setnr_fragsto 1, so the teardown drops a reference on a page we still own. The linear overflow becomes a page use-after-free. The overflow never touchesfrags[0], so it need not be timed against the spray, which is most of what makes it forgiving. -
Page UAF to Dirty-Pagetable. The freed pipe page is reclaimed as a last-level page table by faulting a fresh anonymous mapping. One physical page is now both a live leaf page table and the page the pipe still reads and writes. Writing eight bytes to the pipe installs a forged PTE; reading the pipe reads the table back. This is a finite arbitrary physical read/write, on the order of 460 PTE windows per table.
-
Defeat KASLR. With the physical read we scan the fixed low-memory SMP trampoline page table, which KASLR never relocates; its kernel half entry points at
level4_kernel_pgt, the kernel’s physical base. From thereinit_top_pgt(recognisable by its self-referencing entry 511) is a universal virtual to physical translator, recovering the kernel virtual base and tying our address space to physical memory. -
Finite to infinite read/write. We forge one PTE in the leaf table that points at the table’s own physical address. The matching virtual window then aliases the page table itself, so PTEs become plain memory: unlimited, random access kernel read/write, with no pipe in the loop. Ring 3 TLB coherence is handled by forcing a full mm flush with an oversized
mprotect(). -
Resolve offsets and take credentials. Struct member offsets are read at runtime from
/sys/kernel/btf/vmlinux, not baked in. We locate our owntask_structthrough the vmemmapstruct pagewalk andmm_struct.owner, zero the credential ids, and fill all capability sets oncredandreal_cred. Symbol addresses come from an internal resolver that parses the kernel’s ownkallsymstables through our arbitrary read; only if that fails do we fall back to pointingcred.user_nsatinit_user_ns(soCAP_SYSLOGholds in the initial namespace) and reading the real addresses from/proc/kallsyms. -
Disable SELinux without flipping enforcing. We overwrite the prologue of
avc_denied()with axor eax, eax ; retstub (stepping overendbr64under IBT). Every denial now returns granted, process wide, whilegetenforcestill reportsEnforcing. This is also a prerequisite for the escape: the core-dump handler’s cross domain re-exec would otherwise be denied. -
Escape through core_pattern. We overwrite the global
core_patternwith a|prefixed handler pointing back at our own binary through/proc/<PID>/root(the crashing task’s container chroot), then crash a child. The kernel runs the handler as a usermodehelper, root in the initial namespaces, and we relay an interactive root shell over a Unix socket bound inside the container. The handler is born inside the init namespaces, so no in-place namespace surgery, and none of its PID-namespace hazards, is needed.
Similar Articles
Dirtyfrag: Universal Linux LPE
A report titled 'Dirty Frag' details a universal Linux Local Privilege Escalation (LPE) vulnerability that allows root access on major distributions by chaining two kernel bugs. The disclosure notes that due to a broken embargo, no patches currently exist for this critical security issue.
PwnEscape: Guest-to-Host KVM Escape (CVE-2026-99999)
Pwn.ai researchers detail CVE-2026-99999, a critical Linux networking flaw that allowed guest-controlled checksum metadata to rewrite IPv4 headers after validation, escalating from a 32-byte host-memory disclosure to a full guest-to-host KVM escape discovered during Vercel's $1 million Sandbox challenge.
Fragnesia: New Linux Privilege Escalation Exploit
A new Linux privilege escalation exploit called Fragnesia has been released with proof-of-concept code on GitHub.
Linux Compromises, Broken Embargoes, and the Shrinking Patch Window
A report on three serious Linux local privilege escalation vulnerabilities discovered in May 2026, highlighting breakdowns in the disclosure model and implications for production environments.
Zapscape - Guest to host escape in KVM/x86
Zapscape (CVE-2026-64561) is a KVM/x86 shadow MMU use-after-free vulnerability that allows a guest VM to escape to the host and execute code with kernel privileges. The published PoC demonstrates a full guest-to-host escape targeting AMD SVM/NPT on Linux 7.1.3, posing a serious threat to multi-tenant public clouds.