
Golang rewrite of the Copy Fail (CVE-2026-31431) local privilege escalation exploit, corrupting page cache to gain root on Linux systems.
732 Bytes to Root on Every Major Linux Distribution
CVE-2026-31431 (Copy Fail) is a logic bug in the Linux kernel's authencesn cryptographic template. It allows an unprivileged local user to trigger a deterministic, controlled 4-byte write into the page cache of any readable file on the system.
CONFIG_CRYPTO_AUTHENC (essentially all major distros since 2017)The bug chains two behaviors:
AF_ALG + splice: splice() transfers page cache pages by reference into an AF_ALG socket's scatterlist. For AEAD decryption in-place mode, the tag pages (from the target file's page cache) remain chained to the output scatterlist via sg_chain().
authencesn scratch write: crypto_authenc_esn_decrypt() uses dst[assoclen + cryptlen] (past the tag, into the page cache pages) as scratch space for ESN sequence number rearrangement, writing 4 attacker-controlled bytes and never restoring them.
The corrupted page is never marked dirty, so the on-disk file remains unchanged. But the in-memory page cache is what actually gets read — making the corruption immediately visible system-wide.
The exploit corrupts the page cache of /usr/bin/su (or any setuid binary) with a small shellcode payload, 4 bytes at a time. After all iterations, running su executes the payload and drops to a root shell.
python3 exp.py
go run exp.go
go build -ldflags "-w -s" -trimpath -o exp exp.go
tinygo build -o exp exp.go
| Capability | Details |
|---|---|
| Portable | Same script works on Ubuntu, Amazon Linux, RHEL, SUSE, and more — no per-distro offsets |
This repository is published for educational and defensive research purposes only. Do not use this code on systems you do not own or have explicit permission to test.
| Tiny | Python exploit is ~732 bytes |
| Stealthy | Bypasses VFS write path; page never marked dirty; on-disk checksums unchanged |
| Cross-container | Page cache is shared across containers — container escape vector (see Part 2) |