Devoured - May 01, 2026
Copy Fail: 732 Bytes to Root on Every Major Linux Distribution (20 minute read)

Copy Fail: 732 Bytes to Root on Every Major Linux Distribution (20 minute read)

Tech Read original

A logic bug in Linux kernel's crypto subsystem lets unprivileged users gain root with a 732-byte Python script by corrupting the page cache of setuid binaries.

What: Copy Fail (CVE-2026-31431) is a vulnerability in the Linux kernel's authencesn cryptographic template that allows unprivileged local users to write 4 controlled bytes into the page cache of any readable file, enabling root access by corrupting setuid binaries like /usr/bin/su. The bug affects essentially all Linux distributions shipped since 2017.
Why it matters: Unlike previous privilege escalation bugs that required winning race conditions or version-specific exploits, Copy Fail is a deterministic logic flaw that works identically across all major distributions and architectures since 2017, and it crosses container boundaries because page cache is shared system-wide, making it both a local privilege escalation and a container escape primitive.
Takeaway: Patch your kernel immediately or temporarily disable AF_ALG by blacklisting the algif_aead module with `echo "install algif_aead /bin/false" > /etc/modprobe.d/disable-algif-aead.conf`.
Deep dive
  • The vulnerability stems from a 2017 optimization in algif_aead.c that performs AEAD operations in-place, combined with authencesn's practice of using the destination buffer as scratch space for IPsec Extended Sequence Number byte rearrangement
  • When a user splices a file into a pipe and then into an AF_ALG socket, the socket's scatterlist holds direct references to the kernel's page cache pages for that file, not copies
  • In the in-place design, the output scatterlist is constructed by copying AAD and ciphertext to a user buffer, then chaining the authentication tag pages by reference using sg_chain(), with both req->src and req->dst pointing to the same combined scatterlist
  • authencesn writes 4 bytes at offset assoclen + cryptlen to rearrange ESN bytes for HMAC computation, which crosses from the legitimate output buffer into the chained page cache pages, corrupting the in-memory file
  • The corrupted page is never marked dirty by the kernel's writeback machinery, so the file on disk remains unchanged and standard integrity checks comparing on-disk checksums miss the modification entirely
  • Attackers control which file to target (any readable file), which offset (by choosing splice parameters and assoclen), and which 4-byte value to write (bytes 4-7 of the AAD)
  • The exploit targets /usr/bin/su by injecting shellcode chunks into its .text section in the page cache, then executing it to gain root since su is setuid-root
  • The same 732-byte Python script works on Ubuntu 24.04, Amazon Linux 2023, RHEL 10.1, and SUSE 16 without any per-distribution modifications or version checks
  • The vulnerability has existed silently for nearly a decade, since three seemingly reasonable changes intersected: authencesn's 2011 scratch space usage, AF_ALG AEAD support in 2015, and the 2017 in-place optimization
  • The fix reverts algif_aead.c to out-of-place operation by separating req->src (TX SGL) from req->dst (RX SGL), removing the sg_chain mechanism that linked page cache pages into the writable destination
  • The vulnerability was discovered using AI-assisted research with Xint Code, which scanned the entire crypto subsystem based on the insight that splice() can deliver page cache references to crypto scatterlists
  • The scan was guided by a simple operator prompt noting that splice() can deliver page-cache references of read-only files to crypto TX scatterlists, and completed in about an hour
  • The researchers note the scan identified other high severity vulnerabilities including another privilege escalation bug still under responsible disclosure
  • Because page cache is shared across all processes including container boundaries, Copy Fail enables container escape and Kubernetes node compromise, detailed in a forthcoming Part 2
Decoder
  • AF_ALG: A socket type (address family) that exposes the Linux kernel's cryptographic subsystem to userspace programs without requiring privileges
  • splice(): A system call that transfers data between file descriptors and pipes by passing page references rather than copying data, avoiding expensive memory copies
  • AEAD: Authenticated Encryption with Associated Data, a cryptographic mode that encrypts data while also authenticating additional unencrypted metadata
  • authencesn: An AEAD wrapper in the kernel used by IPsec for Extended Sequence Number support, which rearranges 64-bit sequence numbers for HMAC computation
  • page cache: The kernel's in-memory cache of file contents that serves all reads, memory maps, and program execution, shared across the entire system
  • scatterlist: A kernel data structure representing discontiguous memory regions, used by the crypto subsystem to describe input and output buffers
  • setuid binary: An executable file with the setuid bit set that runs with the privileges of the file owner (often root) rather than the user executing it
  • in-place operation: A cryptographic operation where the same memory buffer serves as both input and output, avoiding the need to allocate separate destination memory
Original article

Copy Fail is a logic bug in the Linux kernel's authencesn cryptographic template that lets unprivileged users trigger a deterministic, controlled 4-byte write into the page cache of any readable file on the system. It can be exploited using a single 732-byte Python script to obtain root on essentially all Linux distributions shipped since 2017. Its discovery was AI-assisted. A patch for the bug is available.