CVE-2026-31431, named “Copy Fail,” is a logic bug in the Linux kernel’s algif_aead module that lets any unprivileged local user corrupt the page cache of a setuid binary and obtain a root shell in seconds. Rated CVSS 7.8 (HIGH), it affects every major Linux kernel released since 2017, and a public proof-of-concept — a 732-byte Python script — is already circulating. This checklist covers step-by-step patch verification commands, Falco and auditd detection rules, module-level workarounds for fleets that cannot immediately update, and Kubernetes exposure assessment.
Background: What Is CVE-2026-31431?
The vulnerability lives in algif_aead.c, the AEAD socket interface of the Linux kernel’s userspace cryptographic API (AF_ALG). The flaw originates from a 2017 in-place optimization that placed live page-cache pages into the writable destination scatterlist of an AEAD operation. When the authencesn cryptographic wrapper writes its output authentication tag, it writes four bytes at offset dst[assoclen + cryptlen] — past the intended output boundary, directly into adjacent page-cache pages.
The result: a deterministic, race-free, controlled 4-byte write into the page cache of any readable file on the host. No heap spray, no timing window, no per-distro offset calculation required.
Theori researcher Taeyang Lee discovered and reported the flaw to the Linux kernel security team on March 23, 2026. The Xint Code Research Team developed the full exploit chain using AI-assisted analysis. The upstream fix — commit a664bf3d603dc3bdcf9ae47cc21e0daec706d7a5 — was merged on April 1, 2026. The CVE was assigned on April 22, 2026, and public disclosure followed on April 29, 2026 alongside the PoC release.
How Copy Fail Works: The Page Cache Write Primitive
The exploit chains three kernel mechanisms to achieve root:
- AF_ALG socket — An AEAD socket opened via the kernel’s userspace crypto interface, accessible to any unprivileged process with no special capabilities or
CAP_*flags. splice()— Transfers pages from a target setuid binary (e.g.,/usr/bin/su) into the AF_ALG socket buffer without copying. Those pages are the live, in-memory page-cache pages backing the binary.authencesnin-place AEAD operation — Triggers the out-of-bounds 4-byte write into the now-writable page-cache page, overwriting instruction bytes in the setuid binary’s in-memory representation.
The corrupted page is never marked dirty by the kernel’s writeback machinery, so the modification is invisible to on-disk integrity tools like AIDE, debsums, or rpm -V. The attacker then executes the modified binary to receive a root shell.
The public PoC at theori-io/copy-fail-CVE-2026-31431 reduces the full chain to approximately 10 lines of Python. The same script roots every major distribution released since 2017 without modification.
Affected Kernel Versions and Distributions
| Kernel series | Last vulnerable | Fixed version |
|---|---|---|
| 6.19.x | 6.19.11 | 6.19.12 |
| 6.18.x | 6.18.21 | 6.18.22 |
| 6.12.x LTS | distro-dependent | distro backport |
| 6.6.x LTS | distro-dependent | distro backport |
| 5.15.x / 5.10.x LTS | distro-dependent | distro backport |
| 7.0+ | not affected | (fix merged upstream) |
Distributions confirmed vulnerable at the time of April 29 disclosure:
- Ubuntu 24.04 LTS (kernel 6.17.0)
- Amazon Linux 2023 (kernel 6.18.8)
- RHEL 10.1 (kernel 6.12.0)
- SUSE 16 (kernel 6.12.0)
- Rocky Linux 9.7
All major distributions received advance notification and had patched kernel packages available at or before public disclosure. The steps below verify whether your installed kernel includes the fix.
Step 1: Verify the Running Kernel Version
uname -r
Cross-reference the output against the fixed versions in the table above. For distribution-packaged kernels, query the package manager for the installed version:
# Debian/Ubuntu
apt-cache show linux-image-$(uname -r) | grep Version
# RHEL / Rocky / AlmaLinux
rpm -q kernel --qf '%{VERSION}-%{RELEASE}\n'
# Amazon Linux 2023
dnf list installed kernel
# SUSE / openSUSE
rpm -q kernel-default --qf '%{VERSION}-%{RELEASE}\n'
If updates are available, apply them:
# Debian/Ubuntu
apt-get update && apt-get upgrade linux-image-$(uname -r)
# RHEL/Rocky
dnf update kernel
# Amazon Linux 2023
dnf update kernel
A reboot is required to activate the new kernel.
Step 2: Check Whether the Vulnerable Module Is Loaded
Even on systems awaiting a maintenance window, verify whether algif_aead is currently loaded — and disable it immediately if so:
lsmod | grep algif_aead
If the module is loaded and the system is unpatched, unload it and persist the blacklist:
# Unload the module (safe even if in use by non-critical processes)
modprobe -r algif_aead 2>/dev/null
# Blacklist it across reboots
echo "blacklist algif_aead" | sudo tee /etc/modprobe.d/disable-algif-aead.conf
echo "install algif_aead /bin/false" | sudo tee -a /etc/modprobe.d/disable-algif-aead.conf
# Rebuild initramfs to include the blacklist
update-initramfs -u # Debian/Ubuntu
dracut --force # RHEL/Rocky/Amazon Linux
Verify after reboot:
modprobe algif_aead && echo "WARNING: module still loads" || echo "OK: module blocked"
Note: algif_aead is used by cryptsetup, systemd-cryptsetup, and kcapi utilities. Audit your fleet for legitimate uses before deploying this blacklist broadly. Disk-encryption workflows on LUKS2 volumes may depend on this module being loadable at boot.
Step 3: Restrict AF_ALG Sockets via Seccomp
For containerized workloads or hosts where blacklisting algif_aead would break legitimate crypto tooling, restrict AF_ALG socket creation at the process level using a seccomp profile. The exploit entry point is socket(AF_ALG, SOCK_SEQPACKET, ...) — socket family 38:
{
"defaultAction": "SCMP_ACT_ALLOW",
"syscalls": [
{
"names": ["socket"],
"action": "SCMP_ACT_ERRNO",
"args": [
{
"index": 0,
"value": 38,
"op": "SCMP_CMP_EQ"
}
]
}
]
}
Apply to Docker containers:
docker run --security-opt seccomp=/etc/docker/seccomp/block-af-alg.json <image>
For Kubernetes, reference the seccomp profile via a SeccompProfile in the pod’s securityContext.
Step 4: Detect Exploitation Attempts with Falco
Deploy the following Falco rule to alert on unexpected AF_ALG SEQPACKET socket creation. The rule excludes known legitimate callers; review the exclusion list for your environment before deploying:
- rule: AF_ALG Page Cache Poisoning Attempt
desc: Detects unexpected AF_ALG SEQPACKET socket creation — prerequisite for CVE-2026-31431
condition: >
evt.type = socket and
socket.domain = AF_ALG and
socket.type = SOCK_SEQPACKET and
not proc.name in (cryptsetup, systemd-cryptsetup, kcapi-enc, kcapi-dgst)
output: >
AF_ALG SEQPACKET socket opened by unexpected process
(user=%user.name pid=%proc.pid comm=%proc.name parent=%proc.pname
container=%container.name image=%container.image.repository)
priority: WARNING
tags: [cve-2026-31431, lpe, page-cache]
Complement with an auditd rule to capture splice() syscalls from processes that have previously opened AF_ALG sockets:
auditctl -a always,exit -F arch=b64 -S splice -k copy_fail_detection
Review flagged events:
ausearch -k copy_fail_detection --start today | aureport --file --summary
Step 5: Check for In-Memory Page Cache Corruption
Because the exploit never marks the corrupted page dirty, on-disk integrity tools will report clean while the in-memory binary is compromised. The most reliable way to eliminate this possibility on a suspect host is to reboot — flushing the page cache — and then run integrity verification:
# Debian/Ubuntu: verify installed package files against package database
debsums -c coreutils passwd
# RHEL/Rocky: verify shadow-utils and coreutils (common targets)
rpm -V shadow-utils coreutils
# Cross-check setuid binaries on disk against a known-good baseline
find /usr/bin /usr/sbin -perm /4000 -exec sha256sum {} \; > /tmp/setuid_baseline.txt
If you need to compare in-memory vs. on-disk state without rebooting, drop the page cache and re-read the file — though note this also evicts legitimate cached data and may impact performance on busy systems:
sync && echo 3 | sudo tee /proc/sys/vm/drop_caches
sha256sum /usr/bin/su
Container and Kubernetes Exposure
The Linux page cache is shared across all containers on the same host. An unprivileged process in a container can corrupt the page cache backing a setuid binary accessible from the host, making Copy Fail a container escape primitive when the container can read host paths via a volume mount or namespace misconfiguration.
Audit your Kubernetes pods for configurations that expand the attack surface:
# Pods sharing host PID or IPC namespace
kubectl get pods -A -o jsonpath=\
'{range .items[*]}{.metadata.namespace}/{.metadata.name}: hostPID={.spec.hostPID} hostIPC={.spec.hostIPC}{"\n"}{end}'
# Privileged containers
kubectl get pods -A -o jsonpath=\
'{range .items[*]}{.metadata.namespace}/{.metadata.name}: privileged={.spec.containers[*].securityContext.privileged}{"\n"}{end}'
Apply PodSecurityAdmission at the restricted level to enforce seccomp profiles, drop NET_RAW, and prohibit hostPID/hostIPC at the cluster level.
Mitigation Checklist
- [ ] Run
uname -r— confirm kernel version is at or above the fixed release for your series - [ ] Apply pending kernel updates via your package manager and reboot
- [ ] Verify
algif_aeadis not loaded:lsmod | grep algif_aead - [ ] On unpatched hosts: blacklist
algif_aeadvia/etc/modprobe.d/and rebuild initramfs - [ ] For containers: apply seccomp profile blocking
socket(AF_ALG, ...)(family 38) - [ ] Deploy Falco rule targeting AF_ALG SEQPACKET socket creation from unexpected processes
- [ ] Add auditd
splicerule and review results for unexpected callers - [ ] In Kubernetes: audit
hostPID,hostIPC, and privileged pod configurations - [ ] On suspect hosts: reboot to flush page cache, then verify setuid binary integrity with
debsumsorrpm -V - [ ] Confirm
cryptsetup/systemd-cryptsetupstill function correctly after applying module blacklist
Conclusion
CVE-2026-31431 combines a nine-year exposure window, a public 10-line PoC, and an in-memory corruption technique that bypasses every on-disk file integrity tool. The priority order is clear: patch and reboot, blacklist algif_aead as an emergency workaround if you cannot, and deploy Falco detection regardless — both to catch exploitation on unpatched hosts and to give you visibility once patched. Container environments need the seccomp profile and a Kubernetes audit before they can be considered mitigated.
See our guide on CVE-2026-3854: GitHub Enterprise Server RCE — Detection and Patch Verification for a comparable patch-verification workflow applied to a critical RCE with active exploitation. →
For any query contact us at contact@cipherssecurity.com

