SecPod
← Back to Blog

CVE-2026-31431: The Nine-Year Kernel Bug Hiding in Plain Sight

Jun 24, 2026
CVE-2026-31431 Copy Fail | Part 1 of 4
| CVE-2026-31431 Copy Fail | Part 1 of 4

CVE-2026-31431: Nine Years in the Dark - Linux Kernel Copy Fail, Page Cache Corruption, and Local Privilege Escalation

May 2026 HIGH, CVSS 7.8 Active Exploitation Confirmed CISA KEV Listed

A 2017 Linux kernel performance optimization silently introduced a local privilege escalation primitive that went undetected for nine years. A 732-byte Python script using only the standard library hands an attacker a root shell on Ubuntu, RHEL, Amazon Linux, SUSE, and every other mainstream Linux distribution - no compilation, no race condition, no per-distro tuning, no retry loops. The exploit was published simultaneously with disclosure on April 29, 2026. CISA confirmed active exploitation two days later.

Vulnerability at a Glance

CVSS 3.1 Score
7.8 High
AV:L / AC:L / PR:L / UI:N / S:U / C:H / I:H / A:H
Qualys QVS
95 / 100
Operational risk far exceeds CVSS base score
Years Exposed
~9 Years
Introduced 2017, disclosed April 29, 2026
Exploit Size
732 Bytes
Pure Python standard library, zero dependencies
Exploit Reliability
Deterministic
No race condition, no timing window, no retries
Privileges Required
Local User Only
Any unprivileged account, no special capabilities
FieldDetail
CVE IDCVE-2026-31431
Vulnerability NameCopy Fail
Affected Componentalgif_aead module, AF_ALG kernel socket interface - authencesn AEAD cipher
Root Cause Commit72548b093ee3 (2017) - in-place AEAD optimization that collapsed src and dst scatterlists
Upstream Kernel FixCommit a664bf3d603d - reverts the 2017 in-place optimization
Vulnerability ClassImproper memory isolation during AEAD crypto operations via AF_ALG sockets (page cache corruption)
Discovered ByTheori and Xint
Disclosure DateApril 29, 2026 - simultaneous exploit release at copy.fail
CISA KEV AddedMay 1, 2026 (BOD 22-01 patch deadline: May 15, 2026)
Affected DistributionsUbuntu, RHEL, AlmaLinux, Amazon Linux 2023, Debian, Fedora, Arch Linux, SUSE, CloudLinux, and any distro shipping a kernel built from the 2017 commit onward
WSL2Affected - WSL2 runs a real Linux kernel; patched via May 2026 Windows Patch Tuesday
Siemens SIMATIC S7-1500Confirmed affected - see SSA-265688 and SSA-082556

Background: What Is the AF_ALG Socket Interface

To understand Copy Fail, it helps to understand why the AF_ALG socket interface exists and what role it plays in the kernel. Linux exposes hardware-accelerated cryptographic operations to userspace through a standard socket family called AF_ALG (address family 38). Instead of requiring applications to perform encryption entirely in userspace, AF_ALG allows a process to hand data to the kernel and receive the cryptographic result back - taking advantage of CPU or hardware crypto acceleration where available.

The interface operates through a two-step setup. First, a process calls socket(AF_ALG, SOCK_SEQPACKET, 0) and binds it to a named algorithm, providing parameters like the cipher suite, key material, and IV. It then calls accept() to receive an operation file descriptor. Subsequent sendmsg() and recvmsg() calls on that operation descriptor trigger the actual cryptographic work.

A critical capability of this interface is support for splice operations. The splice() system call can transfer data between two file descriptors without copying it through userspace. Critically, one of those file descriptors can be a regular file - and when it is, the data being transferred comes directly from kernel page cache, the kernel's shared in-memory buffer for file-backed data. This zero-copy pathway is where Copy Fail creates its opportunity.

Design intent: AF_ALG socket creation requires no special capabilities. Any unprivileged local user can open one. This is intentional - the interface is designed to give userspace access to kernel crypto without elevated privileges. Copy Fail exploits the trust that design places in the kernel's memory isolation between AF_ALG input and output buffers.

The 2017 Commit That Started It All

In 2017, a performance optimization was merged into the Linux kernel for the algif_aead module (commit 72548b093ee3). The change was straightforward in intent: during AEAD (Authenticated Encryption with Associated Data) operations, instead of maintaining separate source and destination scatterlists, the optimization collapsed them into a single combined scatterlist that both req->src and req->dst pointed to simultaneously.

This meant the AEAD implementation would process data in place - reading from and writing to the same memory region. For most AEAD algorithm implementations, this causes no problem. The read completes before any write begins, and the fact that src and dst share the same backing memory is inconsequential.

The authencesn algorithm is different. During its AEAD operation, authencesn uses the destination buffer as a scratch pad before it has finished consuming the source input. When req->src and req->dst both point to the same scatterlist, this scratch write contaminates the data mid-operation. The algorithm writes into the destination region while that same memory is still being read as input. The result is a 4-byte write at an attacker-influenced offset into whatever memory backs the destination scatterlist.

The key insight: Because the attacker feeds page cache pages of a setuid binary (such as /usr/bin/su) into the AF_ALG operation via splice(), those 4 bytes land inside the kernel's in-memory representation of that executable. The on-disk binary is never touched. The modification lives entirely in page cache - and because page cache is shared kernel-wide, every subsequent execution of that binary on the system runs the corrupted in-memory version until the page is evicted.

Step-by-Step: How the Exploit Path Works

# Step 1: Open an AF_ALG socket - no capabilities required
socket(AF_ALG=38, SOCK_SEQPACKET=5, 0)

# Step 2: Bind to the vulnerable AEAD algorithm
bind(fd, {alg_type='aead', alg_name='authencesn(hmac(sha256),cbc(aes))'})

# Step 3: Accept an operation file descriptor
op_fd = accept(fd)

# Step 4: Open the target setuid binary - page cache gets populated
suid_fd = open("/usr/bin/su", O_RDONLY)

# Step 5: Splice page cache pages into the AEAD op fd (zero-copy)
splice(suid_fd, NULL, op_fd, NULL, PAGE_SIZE, 0)
     └── page cache pages of /usr/bin/su now in the writable dst scatterlist

# Step 6: Trigger the AEAD operation
sendmsg / recvmsg
     └── authencesn uses dst as scratch pad
     └── 4-byte write lands in page cache of /usr/bin/su
     └── in-memory binary is now corrupted - disk file unchanged

# Step 7: Repeat ~40 iterations across different page offsets
     └── delivers sufficient corruption to redirect setuid execution

# Step 8: Execute the corrupted setuid binary
exec("/usr/bin/su")
     └── root shell spawned

Why File Integrity Monitoring Cannot See This

One of the most operationally significant properties of Copy Fail is its relationship with file integrity monitoring. Tools like Tripwire, AIDE, and similar FIM solutions work by recording cryptographic hashes of files on disk and alerting when those hashes change. They compare what is stored on disk against a known-good baseline.

Copy Fail never touches the disk. The authencesn scratch write lands in page cache - the kernel's in-memory read buffer for file-backed data. The on-disk bytes of /usr/bin/su remain exactly as they were before exploitation. An sha256sum of the file produces the correct, expected hash. AIDE reports no changes. Tripwire reports no changes. Any audit mechanism that compares inode metadata, file size, timestamps, or disk-level checksums sees nothing.

The modification exists only in the kernel's page cache, a shared in-memory structure with no direct on-disk counterpart. It persists until memory pressure forces eviction or the system reboots. During that window, every process on the system that executes the targeted setuid binary invokes the corrupted in-memory version.

Detection Mechanism Effective Against Copy Fail Reason
Tripwire / AIDE (disk hash) No Hashes on-disk bytes only - page cache modification is invisible
inotify / fanotify (file events) No splice-driven page cache writes do not raise inode change events
SELinux / AppArmor policy Partial Can restrict AF_ALG socket creation - does not detect if already permitted by policy
auditd syscall monitoring Yes AF_ALG socket (family 38) creation by non-root is a high-confidence indicator
eBPF / bpftrace runtime Yes Tracepoint on sys_enter_socket with family=38 and uid!=0 catches it live
Page cache integrity check Yes Comparing in-memory page cache hashes against on-disk checksums reveals the modification
EDR behavioral analysis Yes Unprivileged process acquiring UID 0 without going through sudo or PAM is strongly anomalous
Organizations relying on file-integrity monitoring as a primary host security control should treat their Linux estate as having reduced visibility for Copy Fail exploitation. Detection requires behavioral controls - auditd syscall monitoring and EDR UID-transition detection are the mechanisms that work here. This is covered in full in Part 3 of this series.

Affected Distributions and Scope

Copy Fail affects any Linux kernel built after commit 72548b093ee3 landed in mainline in 2017 and before the April 2026 vendor patches were applied. That window covers essentially every mainstream Linux distribution that shipped kernel packages between 2017 and April 29, 2026.

Distribution Patch Status Notes
Ubuntu Patched Interim kmod blacklist released April 30; full kernel image packages followed in early May 2026
AlmaLinux Patched Patched April 30, 2026 - ahead of upstream RHEL
RHEL / CentOS Stream Patched Patches available; check Red Hat security bulletin for exact build numbers
Amazon Linux 2023 Patched AWS kernel updates released; verify via yum update kernel and reboot
Debian Patched Upstream fix available via standard security update channel
Fedora Patched Rapid release cadence; patched quickly post-disclosure
Arch Linux Patched Rolling release - update via pacman -Syu
SUSE / openSUSE Patched Patches available via SUSE security channels
CloudLinux Patched Patched kernels and KernelCare livepatches available May 1-2, 2026
Windows WSL2 Patched WSL2 runs a real Linux kernel; updated via May 2026 Windows Patch Tuesday
Siemens SIMATIC S7-1500 Advisory Issued SSA-265688 and SSA-082556 - see Siemens CERT portal for per-product remediation
Interim mitigation: If patching cannot be completed immediately, the algif_aead kernel module can be blacklisted without affecting dm-crypt, LUKS, kTLS, IPsec, SSH, or standard OpenSSL and GnuTLS builds. Only applications explicitly using AF_ALG for AEAD ciphers are impacted - an uncommon production configuration. Full patching and mitigation steps are in Part 4 of this series.

How Copy Fail Compares to Previous Linux LPEs

Linux local privilege escalation vulnerabilities are not unusual, but Copy Fail's operational characteristics separate it from its predecessors. The two most comparable high-profile Linux LPEs are Dirty Cow (CVE-2016-5195) and Dirty Pipe (CVE-2022-0847), both of which involved manipulation of page cache or copy-on-write mechanisms. The comparison matters because it clarifies exactly what makes Copy Fail a different class of threat.

Dirty Cow (CVE-2016-5195)
Root causeRace condition in CoW
Exploit typeTiming-dependent
ReliabilityProbabilistic
Per-distro tuningRequired
Compiled payloadRequired
Same script cross-distroNo
Dirty Pipe (CVE-2022-0847)
Root causePipe buffer flag
Exploit typeLogic flaw
ReliabilityHigh
Per-distro tuningPartial
Compiled payloadRequired
Same script cross-distroNo
Copy Fail (CVE-2026-31431)
Root causeCryptographic scratch write
Exploit typeDeterministic logic flaw
Reliability100% deterministic
Per-distro tuningNone required
Compiled payloadNone - Python stdlib
Same script cross-distroYes - all distros

SafeBreach researchers confirmed that the same unmodified 732-byte script produced root shells across Ubuntu, RHEL, Amazon Linux, SUSE, and Arch Linux. No recompilation, no kernel version detection, no per-distro offset tables. This cross-distro reliability means an attacker with local access to any Linux host can immediately attempt privilege escalation without knowing the distribution, kernel version, or installed toolset in advance - a qualitative shift from what previous LPEs required.

The 9-year window is not an anomaly. The 2017 commit was a reasonable performance change reviewed and merged by maintainers with full context. The bug lies in the interaction between the optimization and one specific algorithm's behavior of using its output buffer as scratch space mid-operation. That class of subtle behavioral dependency is exactly what standard code review and automated testing routinely miss - and exactly the class of issue that sits undetected for years until someone looks for it deliberately.

What Is Coming in This Series

Part 1 - This Article
Nine Years in the Dark
Root cause commit, AF_ALG socket mechanics, page cache corruption, FIM blindness, affected distributions, comparison to Dirty Cow and Dirty Pipe
Part 2
The 732-Byte Root
Exploit mechanics deep dive, full syscall chain analysis, container escape scope, Kubernetes node compromise path, WSL2, active exploitation timeline
Part 3
Finding the Footprint
auditd rules, eBPF monitoring, Wazuh SIEM correlation, behavioral IOC taxonomy, YARA memory strings, full MITRE ATT&CK mapping
Part 4
Closing the Door
Per-distro patch verification, algif_aead blacklist procedure, seccomp and AppArmor controls, Kubernetes hardening, vulnerability chaining risks