Executive Summary
CVE-2026-31431 — nicknamed "Copy Fail" — is a local privilege escalation vulnerability in the Linux kernel's cryptographic subsystem. A logic flaw in the algif_aead module, introduced in 2017, allows any unprivileged local user to write arbitrary data into the kernel's in-memory file cache — without ever modifying the file on disk. Here is what that means in practice:
- Any user becomes root — No special permissions, capabilities, or group memberships needed. A regular user account is enough.
- Fully deterministic — Unlike previous kernel exploits, there is no race condition to win. The exploit succeeds every time, on the first try.
- 732 bytes to root — The complete exploit fits in a single Python script shorter than a typical configuration file.
- Nine years of exposure — Every mainstream Linux distribution shipped since 2017 is affected: Ubuntu, RHEL, Debian, SUSE, Amazon Linux, Arch, and more.
- Invisible to forensics — The exploit only modifies the kernel's in-memory file cache. The actual file on disk remains untouched. Standard integrity monitoring tools see nothing.
- Container escape vector — The page cache is shared across container boundaries. A compromised container can escalate to host root.
- Self-cleaning — A reboot wipes the evidence. The corrupted memory is discarded and the original file is reloaded from disk.
- Public exploit code available — Working proof-of-concept exploits for Ubuntu, RHEL, Amazon Linux, and SUSE are publicly available.
The Vulnerability at a Glance
In April 2026, security researchers publicly disclosed a nine-year-old logic flaw in how the Linux kernel handles authenticated encryption. The vulnerability was assigned CVE-2026-31431 with a CVSS score of 7.8 (High). Despite the seemingly moderate score, the real-world impact is critical: any unprivileged local user can obtain root access in seconds.
| Field | Detail |
|---|---|
| CVE | CVE-2026-31431 |
| Nickname | Copy Fail |
| Type | Local Privilege Escalation (LPE) + Container Escape |
| CVSS v3.1 | 7.8 (High) |
| Vector | AV:L/AC:L/PR:L/UI:N/S:U/C:H/I:H/A:H |
| CWE | CWE-669 (Incorrect Resource Transfer Between Spheres) |
| Component | algif_aead / authencesn (AF_ALG crypto interface) |
| Bug Introduced | 2017 — Linux 4.14 (commit 72548b093ee3) |
| Affected Kernels | 4.14 through 7.0-rc (all unpatched) |
| Auth Required | Any unprivileged local user (PR:L) |
| User Interaction | None (UI:N) |
| Disclosed | April 29, 2026 (oss-security) |
| Exploit Status | Public PoC available — weaponized |
Root Cause: Three Safe Subsystems, One Deadly Combination
The vulnerability chains three kernel subsystems that were each independently safe but become exploitable in combination:
1. AF_ALG: Unprivileged Access to Kernel Cryptography
The Linux kernel exposes its cryptographic subsystem to userspace through AF_ALG sockets — a standard socket family (family 38) that allows any unprivileged user to request encryption and decryption operations. No special privileges, capabilities, or kernel modules are required. The socket is created with standard syscalls: socket(), bind(), accept().
2. splice(): Zero-Copy File Transfer via Page Cache
The splice() system call transfers data between file descriptors without copying it through userspace. When splicing from a regular file, the kernel passes page-cache page references directly — the actual memory pages where the kernel caches file contents. This is a performance optimization: instead of copying data, the kernel just hands over pointers to the existing pages.
3. The 2017 In-Place Optimization — The Fatal Change
In 2017, commit 72548b093ee3 optimized the AEAD interface in algif_aead.c to perform encryption and decryption in-place — setting req->src = req->dst. For decryption, the code copied AAD and ciphertext from the transmit buffer into the receive buffer, but chained the authentication tag pages by reference using sg_chain(). After this optimization, page-cache pages from splice() now sat in the writable destination scatterlist.
The Write-Before-Verify Bug
The authencesn AEAD wrapper — used by IPsec for Extended Sequence Number (ESN) support — performs a 4-byte scratch write before verifying the HMAC authentication tag:
// The write-before-verify bug
scatterwalk_map_and_copy(tmp + 1, dst, assoclen + cryptlen, 4, 1);
// ^^^ Writes 4 bytes at offset (assoclen + cryptlen) into the destination scatterlist
// These 4 bytes are the ESN sequence number rearrangement scratch space
// The destination contains page-cache pages from splice()
// HMAC verification happens AFTER this write
// When HMAC fails (EBADMSG), the 4-byte write has already been committed
The result: a controlled 4-byte write primitive against any readable file's cached memory representation, using only standard unprivileged syscalls.
Vulnerable Code Paths
| File | Lines | Role |
|---|---|---|
| algif_aead.c | 235–244, 251–252 | In-place optimization: sets req->src = req->dst |
| af_alg.c | 1049–1064 | splice() path: places page-cache pages into scatterlist |
| authencesn.c | 277–279 | Write-before-verify: ESN rearrangement writes into page cache |
The Exploit Chain: From Unprivileged User to Root
The following is based on publicly available proof-of-concept code and security research. The exploit is fully deterministic — no race conditions, no timing tricks, no brute-forcing.
Phase 1: Socket Setup
The exploit opens an AF_ALG socket (family 38, type SOCK_SEQPACKET) and binds it to the authencesn(hmac(sha256),cbc(aes)) algorithm — specifically chosen because authencesn has the ESN scratch-write behaviour. An arbitrary encryption key is set (the key value doesn't matter — authentication will intentionally fail), and the request socket is obtained via accept().
Phase 2: Page Cache Injection
The target setuid binary (typically /usr/bin/su) is opened read-only. Using splice(), the file's page-cache pages are transferred through a pipe into the AF_ALG request socket. Because splice() operates on page references rather than copies, the kernel's cached pages for /usr/bin/su now sit in the AF_ALG socket's RX scatterlist — in a writable position.
Phase 3: Controlled Write
sendmsg() provides the Associated Authenticated Data (AAD) with the attacker's desired 4-byte value embedded in bytes 4–7 (the seqno_lo field). recv() triggers the in-place decryption. authencesn writes 4 bytes at offset assoclen + cryptlen into the page cache. HMAC verification then fails (EBADMSG) — but the 4-byte write has already been committed to the page cache.
The Exploit in Action
The screenshot below — from the original disclosure — shows the same 732-byte exploit executed across four distributions simultaneously. Each terminal starts as an unprivileged user (uid=1001) and ends at uid=0(root). Same script, four distributions, four root shells:

The Exploit Code: 732 Bytes to Root
The following is the publicly available proof-of-concept exploit, deobfuscated and annotated. The original code uses single-letter variable names and aliased module imports — below is the functional breakdown:
Phase 4–5: Repeat and Execute
The exploit loops through the target binary in 4-byte increments, patching the page-cache representation of /usr/bin/su with a prepared payload — typically overwriting privilege-check logic with shellcode that spawns a root shell. Each iteration creates a new AF_ALG socket and repeats the write primitive at the next offset. Once the binary is fully patched in memory, executing su loads the corrupted version from the page cache. Root shell obtained.
Forensic Evasion: The Ghost in the Page Cache
Copy Fail's page-cache write primitive creates a uniquely difficult forensic situation:
- The corrupted page is never marked dirty — the kernel never schedules it for writeback, so the file on disk remains byte-identical to the original
- Standard file integrity monitoring (AIDE, OSSEC, Tripwire) sees nothing — these tools compare on-disk checksums, and the disk is clean
- Forensic disk imaging shows a clean system — standard incident response procedures based on disk analysis will miss the compromise entirely
- The exploit is self-cleaning — a reboot or memory pressure causes the cache to be evicted. The kernel reloads the original file from disk, and all evidence disappears
- No log entries are generated — the AF_ALG socket operations and splice() calls produce no audit trail by default
Container Escape
What Will Detect It
| Detection Method | Mechanism |
|---|---|
| Syscall auditing | Watch for socket(AF_ALG) + bind(authencesn) + splice() chain from non-crypto processes |
| Kernel log monitoring | Repeated EBADMSG errors from the crypto subsystem — each failed HMAC is one 4-byte write |
| Runtime memory integrity | Compare a running process's in-memory pages (/proc/PID/maps) against the on-disk binary |
| File descriptor monitoring | The PoC leaks FDs — watch for processes with rapidly growing descriptor counts |
| Seccomp policies | Block AF_ALG (family 38) socket creation in container workloads |
Historical Context: The Page-Cache Exploit Lineage
Copy Fail is the third major Linux kernel vulnerability exploiting the page cache for privilege escalation. Each iteration has been more reliable than the last:
| Dirty Cow (2016) | Dirty Pipe (2022) | Copy Fail (2026) | |
|---|---|---|---|
| CVE | CVE-2016-5195 | CVE-2022-0847 | CVE-2026-31431 |
| Mechanism | Copy-on-write race condition | Uninitialised pipe buffer flags | AEAD write-before-verify |
| Deterministic? | No — race condition | Mostly — some alignment constraints | Fully deterministic |
| Write constraints | Timing-sensitive, may crash | Cannot write first byte of page | Arbitrary offset, arbitrary value |
| Exploit complexity | High — requires winning a race | Medium — requires pipe alignment | Trivial — 732-byte Python script |
| Years exposed | 9 years (2007–2016) | 1 year (2021–2022) | 9 years (2017–2026) |
Affected Systems
Every mainstream Linux distribution shipping a kernel between 4.14 (October 2017) and the patched versions is vulnerable. The module (CONFIG_CRYPTO_USER_API_AEAD) is enabled by default in virtually every distribution's kernel configuration.
Confirmed Vulnerable
| Distribution | Tested Kernel | Patch Status (May 2, 2026) |
|---|---|---|
| Ubuntu 24.04 LTS | 6.17.0-1007-aws | Patching |
| Amazon Linux 2023 | 6.18.8-9.213.amzn2023 | Vulnerable |
| RHEL 10.1 | 6.12.0-124.45.1.el10_1 | Patching |
| SUSE 16 | 6.12.0-160000.9-default | Patching |
| Debian | Various | Vulnerable |
| Arch Linux | Latest | Patched |
| Fedora / Rocky / AlmaLinux | Various | Patching |
| CloudLinux 7h, 8, 9, 10 | Various | KernelCare livepatching |
Not Affected
- Linux kernels before 4.14 (pre-2017, before the in-place optimization)
- CloudLinux 7 (legacy kernel path)
- Ubuntu 26.04 "Resolute" and later (shipped with fix)
- Systems compiled with CONFIG_CRYPTO_USER_API_AEAD=n (rare in practice)
The Fix and Patch Status
The upstream fix (commit a664bf3d603d) reverts the 2017 in-place optimization. It separates req->src from req->dst, ensuring page-cache pages from splice() never enter a writable scatterlist. The fix eliminates the in-place complexity since source and destination originate from different memory mappings.
| Kernel Branch | Fixed Version | Commit |
|---|---|---|
| Mainline | 7.0 | a664bf3d603d |
| 6.19.x | 6.19.12 | ce42ee423e58 |
| 6.18.x | 6.18.22 | fafe0fa2995a |
| 6.12.x | 6.12.85 | — |
| 6.6.x | 6.6.137 | — |
| 6.1.x | 6.1.170 | — |
| 5.15.x | 5.15.204 | — |
| 5.10.x | 5.10.254 | — |
Timeline
| Date | Event |
|---|---|
| 2011 | authencesn template added to kernel — ESN scratch write is harmless (internal buffers only) |
| 2015 | AF_ALG AEAD support added with splice() path |
| 2017 (Linux 4.14) | Bug introduced: In-place AEAD optimization merged (commit 72548b093ee3) |
| Apr 1, 2026 | Upstream fix committed to mainline (commit a664bf3d603d) |
| Apr 22, 2026 | CVE-2026-31431 published on NVD |
| Apr 29, 2026 | Public disclosure on oss-security mailing list with working PoC |
| Apr 30, 2026 | Vendor patches begin rolling out — Arch patched, Ubuntu/RHEL/SUSE in progress |
| May 2, 2026 | This advisory published |
Remediation
Patch Now
Update to the patched kernel version for your distribution. Refer to the patch table above for the minimum fixed version in each kernel branch.
Immediate Mitigations (If Patching Is Not Yet Possible)
Three mitigation options are available depending on your distribution and deployment model:
Option 1: Disable Module (Distros with Loadable Module)
echo "install algif_aead /bin/false" > /etc/modprobe.d/disable-algif-aead.conf
rmmod algif_aead 2>/dev/null || true
Option 2: Boot Parameter (RHEL-Family — Module Compiled In)
sudo grubby --update-kernel=ALL --args="initcall_blacklist=algif_aead_init"
sudo reboot
# Verify
grep initcall_blacklist /proc/cmdline
Option 3: Seccomp Policy (Containers / Kubernetes)
Block AF_ALG (family 38) socket creation at the seccomp layer for containerised workloads:
"defaultAction": "SCMP_ACT_ALLOW",
"syscalls": [{
"names": ["socket"],
"action": "SCMP_ACT_ERRNO",
"args": [{
"index": 0,
"value": 38, // AF_ALG = 38
"op": "SCMP_CMP_EQ"
}]
}]
}
Compatibility Impact
Conclusion
Copy Fail represents a new high-water mark for Linux kernel privilege escalation. Unlike its predecessors — Dirty Cow required winning a race condition, Dirty Pipe had alignment constraints — Copy Fail is fully deterministic. The exploit works on the first attempt, every time, against every default kernel configuration shipped since 2017.
The forensic evasion properties make this particularly dangerous for incident response: the attack leaves no trace on disk, generates no log entries by default, and self-destructs on reboot. For organisations running multi-tenant infrastructure — cloud VMs, container platforms, CI/CD systems — any unprivileged process should be treated as a potential root-level threat until the kernel is patched.
The nine-year exposure window (2017–2026) is a sobering reminder that kernel security bugs can hide in plain sight for nearly a decade. The vulnerable code was reviewed, optimised, and maintained by the kernel community for years — yet the cross-subsystem interaction between AF_ALG, splice(), and authencesn was never analysed as a unit until researchers connected the dots.
Patch. Mitigate. Verify.
References
| Resource | URL |
|---|---|
| NVD Entry | nvd.nist.gov/vuln/detail/CVE-2026-31431 |
| CERT-EU Advisory | cert.europa.eu/publications/security-advisories/2026-005 |
| PoC Exploit Repository | github.com/theori-io/copy-fail-CVE-2026-31431 |
| Bug-Introducing Commit | 72548b093ee38a6d4f2a19e6ef1948ae05c181f7 |
| Fix Commit (Mainline) | a664bf3d603dc3bdcf9ae47cc21e0daec706d7a5 |
Vulnerability Assessment
Deep technical analysis of vulnerabilities affecting your infrastructure — beyond CVSS scores to real-world exploitability and impact.
Attack Surface Intelligence
Passive mapping of your external presence — every exposed service, endpoint, and piece of infrastructure visible to the public internet.
Threat Hunting
Proactive detection of compromise indicators, APT activity, and post-exploitation artifacts across your email and identity infrastructure.
Dark Web Monitoring
Continuous surveillance of stolen credential markets, threat actor forums, and data leak channels. Know when you're being targeted before it becomes an incident.