Skip to content

Back to the catalog

xint.iowriteup

Copy Fail (CVE-2026-31431): 9-year-old Linux kernel LPE via AF_ALG/splice()

Xint/Theori researchers detail CVE-2026-31431 ('Copy Fail'), a Linux kernel logic bug where the authencesn AEAD crypto template writes 4 attacker-controlled bytes past its output buffer, and AF_ALG's 2017 in-place optimization chains page-cache pages from splice() into that writable scatterlist. This lets an unprivileged local user corrupt the in-memory page cache of any readable file (e.g. /usr/bin/su) without touching disk, yielding a race-free, portable root exploit in a 732-byte Python script across Ubuntu, Amazon Linux, RHEL and SUSE. The post traces the bug's origin across 2011/2015/2017 kernel commits, walks through the exploit and the out-of-place fix, and notes the flaw was found via an AI-assisted scan (Xint Code) guided by researcher Taeyang Lee.

TL;DR 9-year-old Linux kernel AF_ALG/authencesn/splice() bug (CVE-2026-31431) lets unprivileged users corrupt page-cache pages of any file (e.g. su) for deterministic, race-free root on every major distro.
Document

What it is

Copy Fail (CVE-2026-31431) is a Linux kernel local privilege escalation in the authencesn AEAD crypto template, reachable by any unprivileged user through AF_ALG sockets. It yields a deterministic (no-race, no-retry) controlled 4-byte write into the page cache of any file the user can read. Xint's team confirmed root on Ubuntu, Amazon Linux, RHEL, and SUSE across kernel lines 6.12, 6.17, and 6.18 with a single unmodified 732-byte Python script.

How it works

splice() passes page-cache pages by reference into an AF_ALG socket's scatterlist. Since 2017 (commit 72548b093ee3), algif_aead.c ran AEAD decryption in-place: AAD and ciphertext are copied into the user's RX buffer, but the tag pages are chained by reference (sg_chain) into the writable destination, with req->src = req->dst. authencesn alone among AEAD templates uses the destination as scratch space for ESN sequence-number rearrangement, writing 4 bytes at dst[assoclen + cryptlen] — past the tag — and never restoring them. In the in-place path that write lands in the chained page-cache page. HMAC then fails and recvmsg errors, but the 4-byte write persists.

The attacker controls all three variables: which file (any readable), which offset (via splice offset/length and assoclen), and which value (AAD bytes 4–7).

Preconditions / Affected

  • Kernels with the 2017 in-place optimization: distributions shipped since 2017, confirmed on 6.12–6.18.
  • AF_ALG available to unprivileged users (default) and algif_aead loadable.
  • Python 3.10+ on the target for os.splice (for this specific PoC).
  • Bug crosses container boundaries — page cache is host-shared, making it a container-escape / Kubernetes node-compromise primitive (detailed in the vendor's Part 2, not this post).

What to do

Patch the kernel via normal distribution updates. The upstream fix (a664bf3d603d) reverts AF_ALG AEAD to out-of-place operation, removing the sg_chain of page-cache pages into the writable destination.

Immediate mitigation — block the module or AF_ALG via seccomp:

echo "install algif_aead /bin/false" > /etc/modprobe.d/disable-algif-aead.conf
rmmod algif_aead 2>/dev/null

Caveats

  • Stealth: the corrupted page is never marked dirty, so on-disk file integrity checks (checksum comparison) miss the modification — but the corrupted in-memory version is what execve/read/mmap actually see, system-wide.
  • The default exploit targets /usr/bin/su; the primitive is generic to any readable setuid binary.
  • The scan reportedly found additional high-severity kernel bugs (including another LPE) still under coordinated disclosure — expect follow-on advisories.

Organisations named here

  • authencesn
  • Dirty Cow
  • Dirty Pipe
  • Taeyang Lee
  • Theori

CVEs named here

  • CVE-2026-31431
  • CVE-2016-5195
  • CVE-2022-0847

Technologies named here

  • Xint Code
  • Linux kernel
  • Ubuntu
  • AF_ALG
  • Amazon Linux
  • RHEL
  • SUSE
  • Python

Techniques named here

  • Cross-container page cache corruption