PoC Archive PoC Archive
Critical CVE-2026-31413 patched

Linux BPF Verifier Scalar-Forking Soundness Bug to Container Escape — CVE-2026-31413

by Rat5ak · 2026-07-05

Severity
Critical
CVE
CVE-2026-31413
Category
binary
Affected product
Linux kernel — BPF verifier (maybe_fork_scalars())
Affected versions
6.12.75+ (stable backport dea9989a3f) through 7.0-rc4; introduced by bffacdb80b93 (Linux 7.0-rc1), fixed by c845894ebd6f (Linux 7.0-rc5)
Disclosed
2026-07-05
Patch status
patched

Metadata

FieldValue
Date Added2026-07-05
Last Updated2026-04
Author / ResearcherRat5ak
CVE / AdvisoryCVE-2026-31413
Categorybinary
SeverityCritical
CVSS ScoreNot specified in source
StatusWeaponized
Tagslinux-kernel, ebpf, bpf-verifier, container-escape, modprobe-path, gke, lpe, vtable-hijack
RelatedN/A

Affected Target

FieldValue
Software / SystemLinux kernel — BPF verifier (maybe_fork_scalars())
Versions Affected6.12.75+ (stable backport dea9989a3f) through 7.0-rc4; introduced by bffacdb80b93 (Linux 7.0-rc1), fixed by c845894ebd6f (Linux 7.0-rc5)
Language / PlatformC, Linux kernel (eBPF), container runtimes (tested against GKE nodes)
Authentication RequiredLocal-only (requires CAP_BPF + CAP_PERFMON + CAP_NET_ADMIN, e.g. inside an unprivileged-but-capable container)
Network Access RequiredNo

Summary

The Linux BPF verifier’s maybe_fork_scalars() forks verifier state when it sees an ARSH followed by AND/OR with a constant. The forked (“pushed”) path is generated via push_stack(env, env->insn_idx + 1, ...), which skips the ALU instruction on that path and assumes the destination register is 0. This assumption is correct for AND (0 & K == 0) but wrong for OR (0 | K == K) — so the verifier believes a register holds 0 while the CPU actually computes K. This register-value divergence lets a BPF program with CAP_BPF/CAP_PERFMON/CAP_NET_ADMIN pass verifier bounds checks it should not pass, yielding an out-of-bounds read/write primitive against a BPF map. The included exploit chain leaks the map’s kernel address, forges a fake bpf_map_ops vtable, redirects a map operation to achieve arbitrary write, and overwrites modprobe_path to execute an attacker script as root when the kernel handles an unknown binary format — achieving full container-to-host escape.


Vulnerability Details

Root Cause

push_stack(env, env->insn_idx + 1, ...) in maybe_fork_scalars() causes the verifier’s forked/pushed exploration path to skip the ALU instruction that generated the fork, incorrectly retaining the pre-fork register value (0) instead of the true post-ALU value. For BPF_OR operations this produces a soundness bug: the verifier’s tracked register state (0) diverges from the actual runtime value (K), invalidating every subsequent bounds check that depends on that register.

Attack Vector

  1. Load a BPF program (with CAP_BPF/CAP_PERFMON/CAP_NET_ADMIN, obtainable inside certain container configurations) that performs ARSH 63 (producing {0, -1}), then ORs with a constant, followed by a conditional branch that causes the verifier to fork state.
  2. On the forked path, add the “zero” register (verifier believes 0, CPU computes K) to a BPF map pointer; the verifier approves map_value + 0 while the CPU executes map_value + K, yielding an out-of-bounds map access.
  3. Use the OOB read/write primitive to leak the map’s kernel address (poc/leak_map_addr.c, poc/step1_leak_ops.cstep3_arb_read.c), then build a fake bpf_map_ops vtable and redirect map_push_elem through a controlled pointer (exploit/exploit.c, exploit_or_fork*.c) for arbitrary kernel write.
  4. Overwrite modprobe_path with an attacker-controlled script path.
  5. Trigger execution of an unknown binary format, causing the kernel to invoke the attacker’s script via modprobe_path as root.
  6. Inside a container, this yields full host root and container escape (GKE-specific variants included as exploit_gke.c/exploit_gke_v2.c).

Impact

Arbitrary kernel read/write from a BPF program with limited capabilities, escalating to root code execution on the host and full container escape.


Environment / Lab Setup

Target:   Linux kernel 6.12.75+ .. 7.0-rc4 (container with CAP_BPF + CAP_PERFMON + CAP_NET_ADMIN, e.g. GKE node)
Attacker: gcc/make (Makefile provided), root inside the container to load the BPF program

Proof of Concept

PoC Script

See poc/ (bug validation: validate_bug.c, test_oob.c, leak_map_addr.c, step1_leak_ops.c, step2_oob_rw.c, step3_arb_read.c) and exploit/ (exploit.c, exploit_gke.c, exploit_gke_v2.c, exploit_ctf.c, exploit_or_fork*.c, plus post-exploitation tier2tier10 modules) in this folder, along with the upstream patches/ fixing the bug.

1
2
3
make
./poc/validate_bug        # confirms the verifier soundness bug (KASAN OOB)
./exploit/exploit         # full chain: leak -> vtable hijack -> modprobe_path overwrite -> root

The poc/ programs incrementally validate the verifier bug and the OOB read/write primitive; exploit/exploit.c (and its _gke/_gke_v2 variants targeting Google Kubernetes Engine nodes) chain the primitive into a full container-escape achieving host root via modprobe_path overwrite. patches/ contains the upstream one-line verifier fix and accompanying selftests that were merged into mainline.


Detection & Indicators of Compromise

Signs of compromise:

  • Unexpected changes to /proc/sys/kernel/modprobe
  • BPF programs loaded from container workloads that should not require CAP_BPF/CAP_PERFMON/CAP_NET_ADMIN
  • KASAN/kernel OOB warnings referencing BPF map access shortly before a privilege escalation event

Remediation

ActionDetail
Primary fixApply upstream commit c845894ebd6f (Linux 7.0-rc5) or update to a kernel build incorporating the one-character maybe_fork_scalars() fix (patches/0001-bpf-Fix-unsound-scalar-forking-in-maybe_fork_scalars.patch)
Interim mitigationRestrict CAP_BPF/CAP_PERFMON/CAP_NET_ADMIN from untrusted container workloads; enable seccomp/BPF-program-loading restrictions where feasible

References


Notes

Mirrored from https://github.com/Rat5ak/CVE-2026-31413-BPF-Container-Escape on 2026-07-05. The upstream repository also includes a demo video and additional post-exploitation “tier” modules (credential overwrite, syscall hooking, anti-forensics, persistence, etc.) beyond the core verifier-bug PoC; the large demo video was omitted here per archive size/media conventions, but all C source (exploit chain, validation PoCs, and post-exploitation modules) and the upstream kernel patches are included.