This tracker is no longer updated as all the tracked distros have released fixes.
Summary
| Field | Detail |
|---|---|
| CVE ID | CVE-2026-31431 |
| Alias | Copy Fail |
| CVSS v3.1 | 7.8 High (AV:L/AC:L/PR:L/UI:N/S:U/C:H/I:H/A:H) |
| Component | crypto/algif_aead.c, crypto/af_alg.c, include/crypto/if_alg.h |
| Type | Local Privilege Escalation (LPE) |
| PoC public | 2026-04-29 — 732-byte Python script (Python 3.10+ required) |
| Exploit | theori-io/copy-fail-CVE-2026-31431 |
| KEV listed | BOD 22-01 remediation due 2026-05-15 |
| EPSS | 0.01228 — 79.2th percentile |
An unprivileged local user can perform a controlled 4-byte write into the
page cache of any readable file via the AF_ALG socket interface’s algif_aead
module. Because the page cache is host-wide, this is also a container escape
primitive on shared-kernel multi-tenant hosts. The modification is in-memory
only — the on-disk file is unchanged, so standard file integrity tooling
(checksums, inotify, auditd file watches) will not detect it.
Vulnerable commit range
| Commit | Description |
|---|---|
72548b093ee3 | Introduced — in-place AEAD optimisation, merged ~2017, v4.14 |
a664bf3d603d | Fix — reverts in-place operation; mainline, 7.0-rc7 |
The full fix is a series of 3 commits, not just the algif_aead revert alone. Distro backports must include all three commits to be fully effective.
Every kernel between those two commits (carrying 72548b093ee3 but not
a664bf3d603d or its stable-branch equivalent) is vulnerable.
Upstream fixed versions
| Stable branch | First fixed version | Notes |
|---|---|---|
| mainline | 7.0-rc7 | |
| 6.19.x | 6.19.12 | EOL 2026-04-22 |
| 6.18.x | 6.18.22 | LTS 2028-12 |
| 6.12.x | 6.12.85 | LTS 2028-12 |
Distribution status
Debian
Main reference: Debian Security Tracker
| Release | Fixed version | Advisory | Status |
|---|---|---|---|
| Debian unstable (sid) | 6.19.12-1 | ✅ Fixed | |
| Debian forky | 6.19.14-1 | ✅ Fixed | |
| Debian 13 (trixie) | 6.12.85-1 | DSA-6238-1 | ✅ Fixed |
| Debian 12 (bookworm) | 6.1.170-1 | DSA-6243-1 | ✅ Fixed |
| Debian 11 (bullseye) | 5.10.251-3 | DLA-4560-1 | ✅ Fixed |
A standard upgrade and reboot is sufficient on every supported release:
apt update && apt full-upgrade
reboot
Proxmox Virtual Environment
Main references: Proxmox PVE security advisories · ProxmoxSecurityAdvisory posts
Proxmox ships its own pve-kernel packages, built independently from Debian’s
kernel packages, so the Debian fix timeline above does not apply here.
PSA-2026-00018-1
covers both PVE 9 and PVE 8 across all three kernel series (6.17, 6.14, 6.8).
Note that pve-container must also be updated alongside the kernel — the PSA
lists it as a required fix package (6.1.5+ for PVE 9, 5.3.5+ for PVE 8).
| PVE version | Base OS | Fixed kernel | Fixed pve-container | Status |
|---|---|---|---|---|
| PVE 9 | Debian 13 (trixie) | 6.17.13-6-pve | 6.1.5 | ✅ Fixed |
| PVE 8 | Debian 12 (bookworm) | 6.14.11-7-pve or 6.8.12-22-pve | 5.3.5 | ✅ Fixed |
PVE 9 fixed in the default 6.17 kernel. The 7.0 kernel series
(proxmox-kernel-7.0.0-*-pve) is listed as unaffected.
PVE 8 uses the 6.14 or 6.8 kernel series. Fixed versions are
proxmox-kernel-6.14.11-7-pve (and 6.14.11-7-bpo12-pve for the bookworm
backport variant) and proxmox-kernel-6.8.12-22-pve.
A standard upgrade and reboot is sufficient on both versions:
apt update && apt full-upgrade
reboot
On PVE kernels algif_aead is a loadable module (not built-in as on
Rocky/RHEL), so Option A also works as an interim workaround on unpatched
nodes.
NixOS
Main reference: NixOS security tracker
| Channel | Fixed version | Status |
|---|---|---|
NixOS unstable (linux_6_18) | 6.18.22 | ✅ Fixed |
NixOS 25.11 — default (linux_6_12) | 6.12.85 | ✅ Fixed |
NixOS 25.11 — opt-in (linux_6_18) | 6.18.22 | ✅ Fixed |
NixOS unstable is fixed: The default kernel for the 26.05 (unstable)
cycle has been updated from 6.12 to 6.18. Any nixos-unstable system
updated since 2026-04-11 is running ≥ 6.18.22 and is not vulnerable.
NixOS 25.11 — the situation depends on which kernel package is installed:
Default (
linux_6_12): Fixed.linux_6_12: 6.12.84 -> 6.12.85was cherry-picked intorelease-25.11at 10:03 UTC on 2026-04-30 (commit248336e3, by zowoq). The fix completed Hydra testing and the fullnixos-25.11channel advanced past248336e3by 2026-05-04 — the channel pointer is now26ef669c, confirmed 70 commits ahead of248336e3withbehind_by=0. Runnixos-rebuild switch --upgradeto get the fix.Opt-in (
linux_6_18): Fixed.linux_6_18: 6.18.21 -> 6.18.22was cherry-picked into the 25.11 branch at 12:54:54 UTC on 2026-04-11 (commitb6dd55149b7c, 2 seconds after the unstable commit). Users who opt in to the 6.18 kernel on 25.11 are protected:
In configuration.nix (no longer required now that linux_6_12 6.12.85 is in nixos-25.11):
boot.kernelPackages = pkgs.linuxPackages_6_18;
Note also that 6.19 was EOL’d and removed from the 25.11 branch on
2026-04-23 (commit 8bb44436).
Rocky Linux
Main references: Rocky Linux errata · Red Hat CVE page · Rocky Linux forum thread
| Release | Kernel series | Fixed version | Status |
|---|---|---|---|
| Rocky Linux 10 | 6.12.x | kernel-6.12.0-124.55.1.el10_1 | ✅ Fixed |
| Rocky Linux 9 | 5.14.x | kernel-5.14.0-611.54.1.el9_7 | ✅ Fixed |
| Rocky Linux 8 | 4.18.x | kernel-4.18.0-553.123.1.el8_10 | ✅ Fixed |
Red Hat shipped RHSA-2026:13566 (RHEL 10) and RHSA-2026:13565
(RHEL 9) on 2026-05-04, and RHSA-2026:13577 (RHEL 8 kernel) and
RHSA-2026:13578 (RHEL 8 kernel-rt) on 2026-05-05, covering kernel
and kernel-rt packages across all three releases.
Rocky Linux published RLSA-2026:13566
(Rocky 10), RLSA-2026:13565 (Rocky 9), and
RLSA-2026:13577 (Rocky 8) on 2026-05-06, each
explicitly listing CVE-2026-31431. Apply via dnf update kernel (Rocky
10/9) or yum update kernel (Rocky 8) and reboot.
🚨 Rocky/RHEL module workaround caveat: On all current Rocky/RHEL kernels (8, 9, 10),
algif_aeadis compiled directly into the kernel (CONFIG_CRYPTO_USER_API_AEAD=y), sormmod algif_aeadandmodprobe.dblacklist entries will silently have no effect. You will see no error, but the module remains active. Use the kernel boot parameter workaround (Option B below) instead.
Amazon Linux
Main references: Amazon Linux Security Center · AL2023 · AL2
Amazon Linux has updated their severity rating from Medium (CVSS 5.5) to Important (CVSS 7.8), now matching the NVD/CISA scoring.
Amazon Linux 2023
| Package | Fixed version | Advisory | Status |
|---|---|---|---|
kernel (default) | 6.1.168-203.330.amzn2023 | ALAS2023-2026-1651 | ✅ Fixed |
kernel6.12 | 6.12.80-106.156.amzn2023 | ALAS2023-2026-1650 | ✅ Fixed |
kernel6.18 | 6.18.20-41.237.amzn2023 | ALAS2023-2026-1649 | ✅ Fixed |
All three AL2023 kernel variants received fixes on 2026-05-05. The advisories
confirm the core fix (“crypto: algif_aead - Revert to operating out-of-place”).
Apply via dnf update kernel (or kernel6.12/kernel6.18 as appropriate)
and reboot.
Amazon Linux 2
| Package | Fixed version | Advisory | Status |
|---|---|---|---|
kernel (Core, ~4.14 series) | 4.14.355-281.727.amzn2 | ALAS2-2026-3289 | ✅ Fixed |
kernel (Kernel-5.4 Extra) | 5.4.302-223.469.amzn2 | ALAS2KERNEL-5.4-2026-120 | ✅ Fixed |
kernel (Kernel-5.10 Extra) | 5.10.252-250.1016.amzn2 | ALAS2KERNEL-5.10-2026-116 | ✅ Fixed |
kernel (Kernel-5.15 Extra) | 5.15.202-142.235.amzn2 | ALAS2KERNEL-5.15-2026-101 | ✅ Fixed |
All four AL2 kernel variants received fixes on 2026-05-05. Apply via
yum update kernel and reboot. If you are on a 5.x extras kernel, ensure you
are subscribed to the appropriate extras advisory stream.
Detection
Check whether the module is loaded or built in
If this returns output, algif_aead is loaded as a module:
lsmod | grep algif_aead
If the above is empty, check for a built-in (common on RHEL/Rocky 8+):
grep algif_aead /lib/modules/$(uname -r)/modules.builtin
Or check the kernel config directly:
grep CONFIG_CRYPTO_USER_API_AEAD /boot/config-$(uname -r)
Interpret the output:
=y→ built-in, cannot be unloaded — use Option B=m→ loadable module — use Option A- no output →
AF_ALGAEAD interface unavailable, not vulnerable
Fallback if /boot/config-* is unreadable and CONFIG_IKCONFIG_PROC=y:
zgrep CONFIG_CRYPTO_USER_API_AEAD /proc/config.gz
Non-destructive detector (from the public PoC)
Requires Python 3.10+ for os.splice. On Rocky/RHEL 9 (default Python 3.9),
use the updated PoC PR #66 from the theori-io repo which backports
splice support to older Python.
python3 test_cve_2026_31431.py
Exit codes:
0= not vulnerable2= vulnerable1= test error (Python < 3.10 without the backport patch)
Runtime detection (Falco/Sysdig rule)
Detect exploitation attempts without patching by alerting on any unprivileged
process opening an AF_ALG SOCK_SEQPACKET socket outside known crypto tools
(cryptsetup, veritysetup, kcapi-*, etc.). See the Sysdig blog
for a ready-made Falco rule.
Workaround
What this does NOT break: dm-crypt/LUKS, kTLS, IPsec/XFRM, SSH, OpenSSL/GnuTLS/NSS default builds, kernel keyring. These all use the in-kernel crypto API directly and do not go through AF_ALG.
What may break: Applications explicitly configured to use the afalg
OpenSSL engine, or custom software that binds aead/skcipher/hash sockets
directly. Assess with lsof | grep AF_ALG before applying.
⚠️ Read the platform-specific notes before applying any workaround. On all current Rocky/RHEL kernels (8, 9, 10), the standard modprobe approach silently does nothing. Applying it gives a false sense of protection.
Option A — modprobe blacklist (Debian, AL2023, AL2)
Works only when algif_aead is a loadable module (verify with lsmod
first):
Block the module and prevent it loading on reboot:
echo "install algif_aead /bin/false" | sudo tee /etc/modprobe.d/disable-algif-aead.conf
Attempt to unload if currently loaded (may fail if in use; reboot if so):
sudo rmmod algif_aead 2>/dev/null || echo "Module not loaded or built-in — reboot may be required"
Verify:
lsmod | grep algif_aead && echo "STILL LOADED" || echo "Not loaded"
Option B — kernel boot parameter (Rocky/RHEL 8+, any distro with built-in module)
When algif_aead is compiled in and cannot be unloaded, prevent it from
registering at boot via the initcall_blacklist kernel parameter. This
requires a reboot:
On systems using BLS config (Rocky/RHEL 8+, Fedora, AL2023), add the boot parameter:
sudo grubby --update-kernel=ALL --args="initcall_blacklist=algif_aead_init"
Reboot:
sudo reboot
After reboot, verify the parameter is active:
grep -o 'initcall_blacklist=algif_aead_init' /proc/cmdline \
&& echo "Mitigation active" || echo "NOT ACTIVE — check grubby output"
Risk notes
- Container hosts: The host-wide page cache means a container breakout is possible on shared-kernel deployments (Docker, Kubernetes without microVM or gVisor isolation). Patch or apply Option B before running untrusted workloads.
- CI/CD runners: Self-hosted GitHub Actions, GitLab Runners, and Jenkins agents executing untrusted PR code are directly in scope.
- Forensics: The exploit modifies only the in-memory page cache. The on-disk file is untouched. inotify, auditd file watches, and on-disk checksums will all report clean. Memory forensics or runtime detection (Falco, eBPF) is required.
- Embedded / appliance kernels: May lag significantly behind distro kernel updates. Audit separately.
Note: The exploit does not modify files on disk. The in-place AEAD
operation bypasses set_page_dirty(), so corrupted pages are never marked
dirty and writeback never flushes them to storage. The in-memory corruption
is therefore transient: dropping the pagecache is sufficient to clear it,
and a reboot achieves the same effect.
echo 1 > /proc/sys/vm/drop_caches