Copy Fail — CVE-2026-31431 Linux kernel local privilege escalation

CVE-2026-31431: Copy Fail — A Decade-Old Linux Kernel Privilege Escalation

Summary

CVE-2026-31431, nicknamed Copy Fail, is a critical local privilege escalation (LPE) vulnerability in the Linux kernel that has been silently exploitable since 2017. It requires no race conditions, no kernel-specific offsets, and no special privileges — just a local user account and a 732-byte Python script.

The flaw lives at the intersection of three kernel subsystems: the AF_ALG crypto socket interface, the splice() system call, and the authencesn AEAD algorithm template. When combined, they allow an unprivileged user to write 4 controlled bytes into the page cache of any readable file on the system — including setuid binaries like /usr/bin/su.

DetailValue
CVE IDCVE-2026-31431
VulnerabilityLocal Privilege Escalation (LPE)
SeverityCritical
Affected SystemsAll mainstream Linux distros built between 2017 and patch date
Exploit Size732 bytes (Python 3.10+, stdlib only)
Reliability100% — no races, no offsets, deterministic
Patch Commita664bf3d603d
Discovered byTaeyang Lee (via Xint Code)

How the Vulnerability Works

Copy Fail is a logic flaw, not a memory corruption bug. It emerges from three independent design decisions that were never audited together.

The Three Components

1. authencesn AEAD template (added 2011)

The authencesn algorithm handles AEAD (Authenticated Encryption with Associated Data) with Extended Sequence Numbers. During decryption, it rearranges sequence number bytes by writing 4 bytes of scratch data at offset assoclen + cryptlen of the destination scatterlist. This was safe in 2011 because AF_ALG used separate, isolated buffers.

2. AF_ALG AEAD support (added 2015)

AF_ALG is a kernel interface that exposes the in-kernel cryptographic subsystem to unprivileged userspace. When AEAD support was added in 2015, it initially operated out-of-place, meaning input and output buffers were separate.

3. In-place optimization via splice() (added 2017)

In 2017, an optimization was introduced: if a user calls splice() to feed page cache pages as ciphertext, those same pages are chained directly into the writable destination scatterlist via sg_chain(). This avoids a copy but means page cache pages of real files become writable destinations.

The Bug at the Intersection

When these three pieces combine:

The corrupted page is never written back to disk. On-disk checksums remain valid. File integrity monitoring tools see nothing. But the kernel’s in-memory view of the file is modified.

Exploitation Path

The exploit targets setuid binaries (default: /usr/bin/su):

1. Open AF_ALG socket; bind to authencesn(hmac(sha256),cbc(aes))
2. Craft sendmsg() AAD with target write value in seqno_lo bytes
3. Use splice() to chain target file's page cache as ciphertext
4. Trigger recv() — authencesn writes 4 bytes into page cache
5. HMAC verification fails (expected), but the corruption persists
6. execve() loads the corrupted setuid binary from page cache → root

The entire exploit fits in 732 bytes of pure Python using only os, socket, and zlib from the standard library.

Affected Systems

The vulnerability was introduced by a 2017 kernel commit. Every mainstream Linux distribution built after that point and before the patch is affected.

Confirmed vulnerable:

DistributionKernel Version
Ubuntu 24.04 LTS6.17.0-1007-aws
Amazon Linux 20236.18.8-9.213.amzn2023
RHEL 10.16.12.0-124.45.1.el10_1
SUSE 166.12.0-160000.9-default

Likely also affected: Debian, Arch, Fedora, Rocky, Alma, Oracle, and any other distribution running a kernel from the 2017–2026 window.

Why This Is Particularly Dangerous

Most LPEs require at least one of: a narrow race window, kernel-specific hardcoded offsets, or pre-installed exploit primitives. Copy Fail needs none of these.

The same 732-byte script runs unmodified across all affected distributions.

Beyond single-machine compromise, the implications are severe for shared environments:

Additionally, because the corruption lives only in the page cache (never flushed to disk), the attack is evasion-friendly: file integrity monitoring, IDS tools, and disk-based forensics will not detect it.

Root Cause: Nobody Connected the Dots

The vulnerability is best understood as a latent bug created by three engineering teams, years apart, each making individually reasonable decisions:

“Nobody connected the 2017 in-place optimization to authencesn’s scratch writes or to the splice path’s use of page cache pages.”

This is a textbook example of an emergent vulnerability — safe components that become dangerous at their intersection. The kernel cryptographic API, the splice zero-copy path, and the AEAD algorithm template each work correctly in isolation.

Patch and Mitigations

Kernel Fix

Mainline commit a664bf3d603d reverts algif_aead.c to out-of-place operation. The fix separates req->src (TX scatterlist) from req->dst (RX buffer), ensuring that page cache pages fed via splice() are never placed into a writable scatterlist. The 2017 optimization is removed.

Interim Mitigations (if patching immediately is not possible)

Option 1 — Disable the algif_aead kernel module:

echo "install algif_aead /bin/false" | sudo tee /etc/modprobe.d/disable-algif-aead.conf
sudo modprobe -r algif_aead 2>/dev/null || true

Option 2 — Block AF_ALG via seccomp (for container workloads):

Add a seccomp profile that denies socket(AF_ALG, ...) calls. This prevents the exploit from initializing the crypto socket.

Check if your system is currently exposed:

# Check if algif_aead module is loaded
lsmod | grep algif_aead

# Check kernel version (vulnerable if between 2017 and patch date)
uname -r

Disclosure Timeline

DateEvent
March 23, 2026Initial report sent to Linux kernel security team
March 24, 2026Acknowledgment received
March 25, 2026Patches proposed and reviewed
April 1, 2026Patch committed to mainline (a664bf3d603d)
April 22, 2026CVE-2026-31431 assigned
April 29, 2026Public disclosure

Discovery

The vulnerability was discovered by Taeyang Lee using Xint Code, an AI-assisted security analysis tool. Lee identified AF_ALG + splice() as a high-risk attack surface and used Xint Code to scan the crypto subsystem with specific context about page cache provenance. The tool flagged Copy Fail as the highest severity finding within approximately one hour.

Conclusion

Copy Fail (CVE-2026-31431) is a critical privilege escalation vulnerability that silently affected nearly a decade’s worth of Linux kernel releases. Its combination of reliability, portability, and stealth makes it exceptionally dangerous — particularly in multi-tenant cloud and Kubernetes environments.

If you run Linux, patch now. Apply kernel commit a664bf3d603d or use your distribution’s security update channel. If patching is delayed, disable algif_aead immediately.

References:

Frequently Asked Questions

What is CVE-2026-31431?

CVE-2026-31431, nicknamed Copy Fail, is a critical local privilege escalation vulnerability in the Linux kernel. It allows any local user to gain root access by exploiting a logic flaw where three subsystems — AF_ALG, splice(), and the authencesn AEAD algorithm — interact unsafely to corrupt page cache memory.

Which versions are affected by CVE-2026-31431?

All Linux kernels built after the 2017 in-place splice optimization and before the April 1, 2026 patch are affected. Confirmed vulnerable distributions include Ubuntu 24.04 LTS, Amazon Linux 2023, RHEL 10.1, and SUSE 16, along with likely every other mainstream distribution from that period.

What can an attacker do with CVE-2026-31431?

An attacker can escalate from any local user account to root on the target system. In containerized or multi-tenant environments this also functions as a container escape primitive, since the Linux page cache is shared across container boundaries on the same host.

What does an attacker need to exploit CVE-2026-31431?

Only a local user account on the affected system is required. No elevated privileges, no race conditions, no kernel-specific offsets, and no special tools are needed — the exploit is a 732-byte Python script that uses only the standard library.

How do I fix CVE-2026-31431?

Apply your Linux distribution's security kernel update or manually apply mainline commit a664bf3d603d. If immediate patching is not possible, disable the algif_aead kernel module or add a seccomp profile that blocks AF_ALG socket calls as a temporary mitigation.

Has CVE-2026-31431 been patched?

Yes. The fix was committed to the Linux kernel mainline on April 1, 2026, as commit a664bf3d603d. The patch reverts algif_aead.c to out-of-place operation, preventing page cache pages from ever being placed into a writable scatterlist.

If you found this post helpful, consider buying me a coffee. It keeps me writing!

Buy Me A Coffee