Copy Fail (CVE-2026-31431): a 732-byte Python script roots every Linux distribution shipped since 2017.
Xint and Theori dropped a 732-byte Python exploit on April 29 that turns any unprivileged Linux user into root on every major distribution shipped since 2017. The bug is a page-cache write primitive in the kernel's authencesn AEAD implementation, exploitable via AF_ALG sockets and splice(). The exploit walkthrough, who is in scope, the patches that already exist, and the seccomp + module blacklist mitigations for environments that cannot reboot immediately.
Founder of Valtik Studios. Penetration tester. Based in Connecticut, serving US mid-market.
# Copy Fail (CVE-2026-31431): a 732-byte Python script roots every Linux distribution shipped since 2017.
On April 29, 2026, researchers at Xint and Theori published a working exploit for CVE-2026-31431, a Linux kernel privilege-escalation vulnerability they named Copy Fail. The exploit is 732 bytes of Python that uses only the standard library. It works reliably on every major Linux distribution shipped in roughly the last nine years — Ubuntu, Debian, Amazon Linux, RHEL, SUSE, Arch, Fedora, Rocky, Alma, Oracle Linux. The CVSS rating is 7.8, but the practical severity is closer to 10. Local attacker on any modern Linux box → root. Reliable. Public exploit. Patches available but not yet deployed at scale.
This post walks through what the bug actually is, how the exploit works, what is and is not in scope, and the patch / mitigation guidance for defenders.
What the bug is, in one paragraph
The Linux kernel's cryptographic subsystem includes an algorithm called authencesn (authenticated-encryption with extended sequence numbers), built to support IPsec ESP packets. The implementation rearranges sequence-related data during cryptographic operations and temporarily reuses the destination buffer as scratch memory. When that scratch reuse interacts with how splice() shares page-cache pages between the AF_ALG socket subsystem and the regular VFS, an unprivileged attacker can perform a precisely controlled four-byte write directly into the page cache backing any setuid binary on the system. The attacker chooses which file. The attacker chooses where in that file. The attacker chooses what value to write.
That is the entire bug. Once you can write arbitrary four-byte values to a setuid binary's page cache, you have root by simply patching /usr/bin/sudo (or any setuid root program) into a launcher for a shell of your choice, then executing it.
The exploit walkthrough
The published proof-of-concept follows a specific sequence. The full chain is documented in the Xint blog post; the abbreviated version:
Step 1: Open and configure an AF_ALG socket.
sock = socket.socket(socket.AF_ALG, socket.SOCK_SEQPACKET, 0)
sock.bind(("aead", "authencesn(hmac(sha256),cbc(aes))"))
sock.setsockopt(socket.SOL_ALG, socket.ALG_SET_KEY, b"\x00" * 32)
op = sock.accept()[0]
AF_ALG is available to any unprivileged user by default on essentially every distribution. The authencesn family is what triggers the vulnerable code path.
Step 2: For each four-byte chunk of the desired write, construct a sendmsg() + splice() pair.
The sendmsg() call provides the AAD (authenticated additional data) header. Bytes 4–7 of the AAD carry the four bytes to be written, encoded as the ESP seqno_lo field. The kernel does not treat these bytes as attacker-controlled when it performs the rearrangement.
The splice() call is the trick. Splice moves data between file descriptors without copying through userspace, which means the kernel ends up sharing page-cache pages between the AF_ALG socket and the target file. The attacker uses splice to provide the target file's page cache pages as the supposed ciphertext + authentication tag.
Step 3: Trigger the decrypt.
A recv() on the operation socket triggers the actual decryption. The kernel performs its rearrangement step, which writes the AAD bytes into the buffer it thinks is scratch space. But the buffer is not scratch space — it is the page cache backing the target file. The four bytes land at the chosen offset in the chosen file.
Step 4: Repeat to construct a complete payload.
The full PoC patches /usr/bin/su (or whichever setuid root binary the distribution ships) with a tiny shellcode stub that swaps the binary's behavior to spawn /bin/sh regardless of whether authentication succeeded. The patching is done four bytes at a time. With pipelining the entire root chain runs in well under a second.
Step 5: Execute the patched binary.
$ /usr/bin/su
# id
uid=0(root) gid=0(root)
The setuid bit on the file did not change. The kernel still happily applies it when execve is called. The fact that the binary's contents have been modified by an unprivileged user is invisible to userspace permission checks. The original binary on disk is unchanged — only the page cache copy has been rewritten — so the modification survives until the page is evicted, which on a busy system is essentially never within the attacker's session.
Why this is "every Linux distribution shipped since 2017"
The vulnerable code path was introduced in the 4.10 kernel cycle to support IPsec Extended Sequence Numbers. Every kernel since carried it. The fix landed in mainline in 7.0, with backports to the still-maintained 6.19.x and 6.18.x stable branches.
Most production Linux deployments are not on those branches. They are on distribution-vendored kernels — Ubuntu 22.04 LTS uses 5.15.x, Ubuntu 24.04 LTS uses 6.8.x, RHEL 8 uses 4.18.x, RHEL 9 uses 5.14.x. Each distribution maintains its own backport process. As of disclosure, Ubuntu has shipped patched kernels for 22.04 and 24.04. Debian has shipped patches for bookworm and trixie. Amazon Linux 2 and Amazon Linux 2023 have updates available. RHEL / CentOS / Rocky / Alma have advisories with kernel updates.
The patches exist. The deployment lag is the problem. Most kernels in production are running whatever the host was provisioned with, plus whatever the package manager pulled in if the operator runs unattended-upgrades. A box that has not been rebooted since deployment is still running the vulnerable kernel even after apt-get upgrade ran successfully — kernel updates require a reboot.
What is in scope and what is not
In scope:
- Multi-tenant Linux servers where an unprivileged user might be hostile (university research clusters, shared-hosting environments, CI runners that allow customer-supplied build steps, container hosts with weak isolation between containers and hosts)
- Any Linux box where you can already get unprivileged shell access through any other vulnerability — web shell from an RCE, SSH access from a leaked key, container escape primitive — Copy Fail elevates that to full root
- Embedded Linux systems (routers, IoT devices, point-of-sale terminals) with kernels in the affected range, where the manufacturer is unlikely to ship a patch quickly
Not in scope:
- Boxes where there is no untrusted local user (most personal laptops, single-user VPS instances, dedicated single-purpose servers with strong perimeter controls)
- Hardened seccomp / sandbox environments that block the AF_ALG socket family
The headline-grabbing part is "every Linux distribution shipped since 2017." The realistic threat for most operators is *what an attacker who already has a foothold can now do with that foothold*. Copy Fail is the elevation primitive that turns "they got into a low-privileged container" into "they own the host kernel."
Mitigations beyond patching
If you cannot reboot to a patched kernel immediately:
Blacklist the algif_aead module. Add blacklist algif_aead to /etc/modprobe.d/ and unload the module if it is currently loaded. The vulnerable path lives in this module. Kernel features that need it (notably some IPsec configurations) will break, so test before deploying widely.
Restrict AF_ALG via seccomp. If your workloads do not need user-space cryptography via AF_ALG, add a seccomp filter that blocks socket(AF_ALG, ...). Container runtimes including containerd and CRI-O have seccomp profile mechanisms that can deploy this cluster-wide.
Restrict AF_ALG via ALSR or Linux capabilities. AF_ALG socket creation can be restricted to processes with CAP_NET_ADMIN. Most workloads do not require this capability and will not notice the restriction.
Detect exploitation attempts. auditd rules on socket(AF_ALG, ...) calls flag any unprivileged process that opens AF_ALG sockets. In environments where AF_ALG is rare, this is a high-fidelity signal.
The pattern Copy Fail represents
Linux kernel privilege-escalation bugs land roughly every 12-18 months at this severity level. Dirty COW, Dirty Pipe, Dirty Stream, the recent nf_tables family, now Copy Fail. Each one teaches the same lesson: the kernel's separation between unprivileged userspace and root is one logic flaw away from disappearing.
The defender's posture is layered. Patching is the top layer, but it is reactive. The deeper layers are:
- Reducing the population of unprivileged-but-not-trusted users on production systems. CI runners that execute customer code should not be on the same kernel as production. Container escapes are a known threat; the elevation primitive that follows the escape becomes catastrophic when bugs like this exist.
- Treating local privilege escalation as a *when*, not an *if*. Defense in depth: AppArmor / SELinux profiles, audit logging on privilege boundary crossings, rapid host rotation so a compromise has limited dwell time before the host gets retired.
- Patching as a process, not an event. The patches for Copy Fail were available within hours of disclosure for major distributions. The boxes that are still vulnerable two weeks from now are not vulnerable because patches do not exist — they are vulnerable because no one has rebooted them.
How Valtik helps
We audit Linux fleets for kernel patch coverage, AF_ALG / seccomp posture, and the privilege-escalation paths that turn small footholds into full host compromise. If you operate a multi-tenant Linux environment — research compute, CI/CD, container hosts, shared infrastructure — Copy Fail is exactly the class of bug your audit posture should be sized for. Free external check at valtikstudios.com/free-check. Direct contact: contact@valtikstudios.com.
Want us to check your Linux Kernel setup?
Our scanner detects this exact misconfiguration. plus dozens more across 38 platforms. Free website check available, no commitment required.
