
Research and detection toolkit for Linux kernel LPE CVE-2026-31431, including exploit analysis, YARA rules, auditd/Falco detection, patching guide, and lab environment.
algif_aead Local Privilege EscalationCISA KEV | CVSS 7.8 HIGH | Affects Linux kernels 4.14 – early 2026 (~9 years)
CVE-2026-31431, nicknamed "Copy Fail", is a high-severity local privilege escalation (LPE) vulnerability in the Linux kernel's cryptographic subsystem. A low-privileged local user can escalate to root in seconds on any unpatched system.
| Attribute | Value |
|---|---|
| CVE | CVE-2026-31431 |
| Nickname | Copy Fail |
| CVSS v3.1 | 7.8 HIGH |
| Attack Vector | Local |
| Privileges Required | Low |
| User Interaction | None |
| Component | crypto/algif_aead.c — authencesn template |
| Introduced | 2017 (commit 72548b093ee3) |
| Disclosed | 2026 |
| Years Silent | ~9 years |
| CISA KEV | Yes |
| Public PoC | Yes (732-byte standalone Python script) |
echo "install algif_aead /bin/false" | sudo tee /etc/modprobe.d/disable-algif-aead.conf
sudo rmmod algif_aead 2>/dev/null || true
detection/check_vulnerable.sh before and after remediation.CVSS:3.1/AV:L/AC:L/PR:L/UI:N/S:U/C:H/I:H/A:H
| Metric | Value | Rationale |
|---|---|---|
| Attack Vector | Local | Requires shell access (SSH, container exec, physical) |
| Attack Complexity | Low | Reliable, fully automated — no race condition required |
| Privileges Required | Low | Any unprivileged user account |
| User Interaction | None | No victim interaction needed |
| Confidentiality | High | Full system compromise |
| Integrity | High | Full system compromise |
| Availability | High | Full system compromise |
| Factor | Assessment |
|---|---|
| PoC Availability | Public, weaponized, 732-byte standalone Python |
| Exploit Reliability | High — works across tested distros without modification |
| Detection Difficulty | High — no disk writes, no dirty pages |
| Attacker Skill Required | Low — script kiddie with public PoC |
| CISA KEV | Added 2026 — actively monitored |
| Microsoft Defender | Flagged as under active investigation |
| Environment | Risk |
|---|---|
| Bare-metal Linux servers | Critical |
| Linux VMs (cloud or on-prem) | Critical |
| Kubernetes nodes | Critical (also enables container escape) |
| Docker hosts | Critical |
| Shared hosting / multi-tenant | Critical |
| WSL2 / Linux on Windows | Assess per kernel version |
The Linux kernel exposes cryptographic operations to userspace via AF_ALG sockets (AF_ALG = 38). This interface (algif_aead) allows unprivileged applications to invoke kernel crypto hardware accelerators without needing kernel-mode code.
AEAD (Authenticated Encryption with Associated Data) algorithms like AES-GCM and ChaCha20-Poly1305 are widely used for TLS, disk encryption, and VPN protocols. The vulnerable template is authencesn — an AEAD composition using hmac(sha256) + cbc(aes) with Extended Sequence Number (ESN) support, commonly used in IPsec.
In 2017, commit 72548b093ee3 introduced in-place AEAD operation to algif_aead as a performance optimization — allowing the crypto engine to read and write the same buffer. This was flawed:
The bug chain:
1. Caller binds AF_ALG socket to:
authencesn(hmac(sha256),cbc(aes))
2. Caller sends a decryption request via sendmsg() with specific flags
3. Caller uses splice() to feed PAGE CACHE PAGES from an open file
descriptor directly into the socket's scatterlist
4. The authencesn template, during ESN header processing, uses the
OUTPUT BUFFER as scratch space — writing 4 bytes past the
expected output boundary
5. Because the scatterlist contains page cache pages (not private
copies), this scratch write lands DIRECTLY IN THE PAGE CACHE
6. Page cache is shared kernel-wide — all processes reading the
same file now see the modified bytes
Key insight: splice() is zero-copy — it hands page cache references
to the socket. The in-place "optimization" then writes INTO those
pages. No dirty bit is set because the write goes through the crypto
engine, not the normal write path.
The vulnerability provides a controlled 4-byte write into the page cache of any file the attacker can open for reading:
| Property | Value |
|---|---|
| Write size | 4 bytes |
| Offset control | Yes — attacker-controlled via splice offset |
| Target | Page cache of any readable file |
| Dirty page marking | None |
| On-disk modification | None |
| Timestamp update | None |
| Kernel log entry | None (unless auditd configured) |
The write is repeatable — the exploit loops the 4-byte write to patch larger code sequences.
[1] Open /usr/bin/su (or any setuid-root binary) for reading
↓
[2] Map a copy to find target instruction bytes
(e.g., UID check, execve path, security gate)
↓
[3] Compute exact page cache offset of target bytes
↓
[4] Set up AF_ALG socket → authencesn(hmac(sha256),cbc(aes))
↓
[5] splice() the target binary's page cache into the socket
↓
[6] Trigger decryption → authencesn scratch write patches
the target bytes in page cache (4 bytes per iteration)
↓
[7] Repeat for each 4-byte patch needed
↓
[8] Execute /usr/bin/su → runs root-owned setuid binary
but now with attacker-controlled code in page cache
↓
[9] Root shell
| Defense | Bypassed? | Reason |
|---|---|---|
| File Integrity Monitoring (Tripwire/AIDE) | Yes | No on-disk change |
| IDS file hash checks | Yes | Disk bytes unchanged |
inotify file watch | Yes | No VFS write event |
| SELinux / AppArmor | Partial | Controls process, not page cache write via crypto engine |
| Read-only mounts | Yes | Page cache modified in-memory, not via mount |
auditd watch on binary | Yes | Audit watches VFS writes — this bypasses VFS |
| Branch | Vulnerable Through | Fixed From |
|---|---|---|
| 4.14.x | All (vulnerability origin) | No upstream fix (EOL) |
| 5.4.x (LTS) | All | Distribution backport required |
| 5.10.x (LTS) | All | Distribution backport required |
| 5.15.x (LTS) | All | Distribution backport required |
| 6.1.x (LTS) | ≤ 6.1.129 | 6.1.130+ |
| 6.6.x (LTS) | ≤ 6.6.86 | 6.6.87+ |
| 6.12.x (LTS) | ≤ 6.12.22 | 6.12.23+ |
| 6.15-rc | Fixed in rc | 6.15-rc+ |