CVE-2026-31431 Copy Fail: An Ubuntu Kernel Flaw That Grants Root From Any Local Account
CVE-2026-31431, nicknamed “Copy Fail,” is a local privilege escalation vulnerability in the Linux kernel’s AF_ALG crypto interface, and it’s unusually bad for two reasons: the bug has existed since a commit from August 2017, meaning it’s been sitting in every mainline kernel for almost nine years, and exploitation is reliable, not probabilistic, an unprivileged local user can use it to write controlled bytes into the page cache of any readable file and escalate straight to root.
Active exploitation has been reported since disclosure. If you haven’t specifically verified your fleet against this one, this post includes a real check run against our own production web server, including a methodology point worth catching: comparing raw kernel version numbers against the generic advisory can genuinely mislead you.
What actually happens
The flaw lives in the kernel’s algif_aead module, the AEAD (authenticated encryption) socket interface of the AF_ALG userspace crypto API. A logic bug in the authencesn cryptographic template, traced back to an in-place optimization added in 2017, lets an unprivileged local process place a page-cache page into a writable destination scatterlist. The practical effect is that a local attacker can write 4 controlled bytes into the page cache of any file they can read, including files they shouldn’t be able to write to, and leverage that into a reliable path to root. This isn’t a crash-and-hope kind of bug, security researchers describe it as reliably exploitable.
Why checking your kernel version alone isn’t enough
The generic advisory lists the fix as landing in upstream kernel versions 6.18.22, 6.19.12, and 7.0. If you’re running a distribution kernel, Ubuntu’s, Red Hat’s, SUSE’s, your installed version number almost certainly doesn’t match any of those directly, distributions backport security fixes into their own versioning scheme without jumping to the matching upstream release. Comparing your uname -r output against “6.18.22” and concluding you’re vulnerable because your number is lower is a genuine, easy mistake.
The right check is your distribution’s own security advisory for this specific CVE. Here’s what that looked like against our own box, a production Ubuntu 24.04 web server running the Oracle-flavor kernel:

Ubuntu’s security team ships the fix for this CVE through their own `linux-oracle-6.17` package line, with the fix landing in build `6.17.0-1018.18~24.04.1` and later. Our installed build here is `6.17.0-1020.20`, past that fixed build, so this specific box is patched, despite the raw version number looking nothing like the upstream “6.18.22” figure from the generic advisory. That gap between “my version number is lower than the one in the advisory” and “am I actually patched” is exactly where this kind of check goes wrong if you don’t look up your specific distribution’s own tracked fix version.
Step 1: find your distribution’s specific fixed version
Search your distribution’s security advisory database for this CVE by number, don’t rely on the generic upstream version figures:
- Ubuntu: Ubuntu Security Notices (USN) for CVE-2026-31431, specific to your kernel flavor (generic, oracle, aws, azure, gcp, hwe all have separate tracked fixes).
- Red Hat / AlmaLinux / Rocky: the vendor’s CVE page, which lists the fixed package version per RHEL major release.
- Debian / SUSE: the distribution’s own security tracker, same CVE number.
Step 2: compare your installed version against it
# Ubuntu/Debian
uname -r
apt-cache policy linux-image-$(uname -r)
# RHEL/AlmaLinux/Rocky
uname -r
rpm -q kernel --last 2>/dev/null || rpm -q kernel-core
Step 3: if you can’t patch immediately, blacklist the module
Blacklisting algif_aead removes the vulnerable code path from being loadable at all. Most systems don’t rely on the AF_ALG kernel crypto interface directly, userspace cryptography libraries don’t need it, so this is a reasonably low-risk interim mitigation while you schedule the actual kernel update.
echo "blacklist algif_aead" | sudo tee /etc/modprobe.d/blacklist-algif-aead.conf
sudo rmmod algif_aead 2>/dev/null # only if currently loaded
sudo update-initramfs -u # Debian/Ubuntu, or dracut --force on RHEL-based
This is a mitigation, not a fix, schedule the actual kernel update and reboot as soon as your maintenance window allows.
Quick guide
- Run
uname -rto get your exact installed kernel build. - Look up your distribution’s specific advisory and fixed build number for CVE-2026-31431, don’t compare directly against the generic upstream version figures.
- If you’re behind the fixed build, schedule the kernel update and a reboot.
- If you can’t patch immediately, blacklist
algif_aeadas an interim mitigation. - Repeat the check across your fleet, not just one representative box, different kernel flavors (generic, oracle, aws, azure) have different fixed build numbers.
FAQ
Does this require any special access to exploit?
No, that’s the severity driver here. Any unprivileged local user account, including a compromised low-privilege service account or a legitimate but limited shell user, is enough to attempt the exploit. There’s no requirement for existing elevated access.
Can this be exploited remotely?
No, it’s a local privilege escalation, it requires existing local code execution on the target system first (from a web shell, a container escape attempt, a compromised application, or legitimate but limited shell access). It’s typically chained with a separate initial-access vulnerability rather than being the first step of an attack.
Does this affect containers, not just full VMs?
Yes, since containers share the host kernel, a vulnerable host kernel can potentially let a process inside a container escalate privileges on, or escape to, the host, depending on the container runtime’s isolation configuration. Patch the host kernel, not just the container images.
Why blacklist algif_aead instead of just disabling the kernel crypto API entirely?
The kernel crypto API backs other legitimate functionality (disk encryption, IPsec, some VPN implementations) that you likely don’t want to break. Blacklisting the specific vulnerable module (the AEAD socket interface) rather than the whole subsystem targets just the exploitable code path.
