🩹 Copy Fail Security Advisory

security advisory / survival guide

Copy Fail: local privilege escalation in the Linux kernel crypto interface (algif_aead)
CVE-2026-31431     CVSS 7.8 (High)     disclosed April 29, 2026     Red Hat: Important     Ubuntu: High

Copy Fail lets an ordinary, unprivileged local user become root by abusing a bug in the kernel's crypto interface for user programs. It is reliable (a logic error, not a race or a lucky timing window), a working proof of concept was published on the day of disclosure, and it works on nearly every mainstream distribution that shipped a kernel between 2017 and the fix. It needs local access first (an SSH login, a web shell, a container, a shared account), so it is not a remote attack by itself, but on any machine where more than one person or process can run code it is serious. This sheet covers what it is, the module involved, how to check your exposure, the manual mitigation for Ubuntu and for Red Hat (they are different!), and which kernel versions are fixed.
Versions and advisories below were checked against the Ubuntu and Red Hat pages on 2026-09-29. A kernel NEWER than the one listed also contains the fix. Always confirm with your own package manager (see "Is my kernel patched?").
Defensive notes only: no exploit code here. Only run the mitigation on machines you own or administer.

What it is, in plain English

Linux lets ordinary programs ask the kernel to do encryption for them through a special kind of socket called AF_ALG. One part of that interface, the module algif_aead, handles "authenticated encryption". In 2017 the kernel was changed to do that work "in place" (reading and writing the same memory) as a speed optimisation. Combined with two older pieces of code, that change left a hole: the encryption code writes four bytes past where it should, and those bytes can land in the kernel's page cache, the in-memory copy of files. A local user can use that to change the cached copy of a file they are only allowed to read, such as su or sudo, and become root. The file on disk is never modified, which is why it is sneaky.
Because the page cache is shared by the whole machine, a container can use this to reach the host. Upstream, the fix (mainline commit a664bf3d603d, April 2026) reverts the module to working out of place, so cached pages are only ever read. Reported vulnerable upstream range: Linux 4.14 up to 6.19.12.
Palo Alto's Unit 42 reported test activity in the wild shortly after disclosure; no widespread campaign was confirmed in the sources checked. Treat it as "public exploit, patch now".

Who is affected

Ubuntu:          14.04 to 25.10. Only the 4.15 kernels on 14.04 (Azure) and 16.04 are affected, their 3.13 and 4.4 kernels are not. 26.04 is NOT affected.
Red Hat family:  RHEL 8, 9 and 10 and products on its kernel (OpenShift 4, ROSA, ARO, OSD). RHEL 6 and 7 are NOT affected.
Others:          Debian, SUSE, Amazon Linux, AlmaLinux, Rocky Linux and other distributions published their own fixes. Follow their advisories.
Lower risk:      machines where nobody untrusted can run code. Still patch them.

The kernel module involved

Module         What it is                                                      Where it lives
algif_aead     AEAD (authenticated encryption) interface of the AF_ALG API     Ubuntu: a loadable module.   RHEL: built INTO the kernel.
That difference decides the mitigation. On Ubuntu you can stop the module loading. On RHEL you cannot block a built-in module with modprobe, so Red Hat uses a kernel boot argument instead (see below).
What breaks if you block it: programs that use the kernel crypto API through AF_ALG sockets (for example the OpenSSL "afalg" engine, if configured) lose that path. Ubuntu says applications should fall back to their own userspace crypto, but some might not, so test first. Most servers never notice.
Related: Dirty Frag (CVE-2026-43284 / 43500) is a DIFFERENT bug with a similar effect, in esp4/esp6/rxrpc. Blocking algif_aead does NOT protect you from Dirty Frag, and blocking esp4/esp6 does not protect you from Copy Fail. Patch the kernel and you are covered for both. See the Dirty Frag sheet on this tab.

Check your exposure first

uname -r                                                       # the kernel you are running RIGHT NOW (compare with the tables below)
lsmod | grep algif_aead                                        # loaded at this moment? (prints nothing if it is not loaded, or built in)
grep -E 'CONFIG_CRYPTO_USER_API_AEAD=' /boot/config-$(uname -r)
                                                               # =m: a module (can be blocked with modprobe)   =y: built in (needs the boot argument or a patched kernel)
cat /proc/cmdline                                              # look here for initcall_blacklist=... if you applied Red Hat's boot argument
ls /etc/modprobe.d/ | grep -i algif                            # any block file already installed (Ubuntu's kmod update installs one automatically)

Manual mitigation: Ubuntu (as published by Ubuntu)

Ubuntu released a kmod package update on the disclosure day (April 29, 2026) that blocks the module automatically, so a fully updated Ubuntu system may already have the block. Fixed kmod versions are listed below. To do it by hand:
1. Block the module from loading:
   echo "install algif_aead /bin/false" | sudo tee /etc/modprobe.d/manual-disable-algif_aead.conf
2. Unload it if it is already loaded (errors hidden if it is not):
   sudo rmmod algif_aead 2>/dev/null
3. Verify:
   grep -qE '^algif_aead ' /proc/modules && echo "Affected module is loaded" || echo "Affected module is NOT loaded"
   modprobe -n -v algif_aead                                   # should print: install /bin/false
If something was already using the module, a reboot may be needed so applications switch to their fallback.
Undo it later (after you have installed the patched kernel and rebooted into it):
   ls /etc/modprobe.d/ | grep -i algif                         # see which block file(s) exist on THIS machine
   sudo rm /etc/modprobe.d/manual-disable-algif_aead.conf      # the file from step 1
   sudo sed -i 's/^/#/' /etc/modprobe.d/disable-algif_aead.conf   # Ubuntu's own steps comment out the kmod-installed file this way (file name as given in Ubuntu's advisory)
   sudo reboot

Manual mitigation: Red Hat / RHEL family (as published by Red Hat in RHSB-2026-002)
The module is built into the RHEL kernel, so "install algif_aead /bin/false" does nothing there. Red Hat documents kernel boot arguments that stop the affected code from initialising. Red Hat's warning: there may be performance impacts for anything that uses kernel cryptographic functions. Pick ONE:
   initcall_blacklist=algif_aead_init               blocks the affected AEAD interface only (the narrowest option)
   initcall_blacklist=af_alg_init                   blocks the whole AF_ALG interface (broader)
   initcall_blacklist=crypto_authenc_esn_module_init   blocks the affected algorithm (authencesn) instead
Add it to every installed kernel with grubby (the usual RHEL way to change boot arguments), then reboot:
   sudo grubby --update-kernel=ALL --args="initcall_blacklist=algif_aead_init"
   sudo reboot
Verify after the reboot:
   cat /proc/cmdline                                           # should contain initcall_blacklist=algif_aead_init
Undo it later, after you are running the patched kernel:
   sudo grubby --update-kernel=ALL --remove-args="initcall_blacklist=algif_aead_init"
   sudo reboot
To block more than one function, put them in ONE argument separated by commas (initcall_blacklist=a,b) instead of repeating the argument, and check that your current command line does not already have one (cat /proc/cmdline) before adding another.
The Red Hat bulletin itself lists the boot arguments; the grubby commands are the standard way to apply them on RHEL 8, 9 and 10.

The real fix: install the patched kernel and REBOOT

Ubuntu:
   sudo apt update && sudo apt upgrade
   sudo reboot
Red Hat / RHEL:
   sudo dnf upgrade --refresh 'kernel*'
   sudo reboot
A kernel update does nothing until you boot into it. Run uname -r afterwards and compare with the tables below.
Ubuntu's unattended-upgrades (on by default from 16.04) installs the update within about a day, but it never reboots for you. Red Hat also published kpatch live patches for some RHEL streams, but a normal update plus reboot is the sure route.
Already installed the Dirty Frag kernels? Then you are covered for Copy Fail too (Ubuntu 18.04 to 25.10 and RHEL): the Dirty Frag kernels are the same build or a newer one than the ones listed below.

Patched kernels: Ubuntu (first fixed versions; anything newer is also fixed)
Release              Kernel line              Fixed in
18.04 LTS Bionic     Linux 4.15               4.15.0-250.262
18.04 LTS Bionic     Linux 5.4 (HWE)          5.4.0-230.250~18.04.1
20.04 LTS Focal      Linux 5.4                5.4.0-230.250
20.04 LTS Focal      Linux 5.15 (HWE)         5.15.0-179.189~20.04.1
22.04 LTS Jammy      Linux 5.15               5.15.0-179.189
22.04 LTS Jammy      Linux 6.8 (HWE)          6.8.0-117.117~22.04.1
24.04 LTS Noble      Linux 6.8                6.8.0-117.117
24.04 LTS Noble      Linux 6.17 (HWE)         6.17.0-29.29~24.04.1
25.10 Questing       linux                    6.17.0-29.29
26.04 LTS Resolute   linux                    not affected
16.04 Xenial         Linux 4.15 only          4.15.0-251.263~16.04.1
Cloud kernels (linux-aws, linux-azure, linux-gcp, linux-oracle) have their own numbers: look them up on https://ubuntu.com/security/CVE-2026-31431. Ubuntu noted that some azure-fde and azure-nvidia variants were still being worked on when the CVE was published, so check the tracker for those.
18.04 and earlier are past standard support: their fixes come through Ubuntu Pro (ESM).
Fixed kmod package (the automatic module block), if you rely on that instead of the kernel:
   22.04: 29-1ubuntu1.1     24.04: 31+20240202-2ubuntu7.2     25.10: 34.2-2ubuntu1.1     26.04: no update needed
   20.04: 27-1ubuntu2.1+esm1     18.04: 24-1ubuntu3.5+esm1     16.04: 22-1ubuntu5.2+esm1     14.04: 15-0ubuntu7+esm1
The kmod block is a stopgap. The kernel update is the real fix.

Patched kernels: Red Hat Enterprise Linux (kernel package; "or newer" applies)
RHEL 10.2   6.12.0-211.7.3.el10_2     (RHSA-2026:19074, May 19 2026)
RHEL 10.1   6.12.0-124.55.1.el10_1    (RHSA-2026:13566, May 4 2026)
RHEL 9.8    5.14.0-687.5.3.el9_8      (RHSA-2026:19225, May 19 2026)
RHEL 9.7    5.14.0-611.54.1.el9_7     (RHSA-2026:13565, May 4 2026)
RHEL 8.10   4.18.0-553.123.1.el8_10   (RHSA-2026:13577, May 5 2026)
RHEL 7 and RHEL 6: not affected.
Extended-support streams (EUS, AUS, TUS, SAP) each have their own fixed kernel:
   10.0 EUS  6.12.0-55.71.1.el10_0       9.6 EUS  5.14.0-570.112.1.el9_6      9.4 EUS  5.14.0-427.124.1.el9_4
   9.2       5.14.0-284.169.1.el9_2      9.0      5.14.0-70.178.1.el9_0       8.8      4.18.0-477.139.1.el8_8
   8.6       4.18.0-372.191.1.el8_6      8.4      4.18.0-305.190.1.el8_4
Rebuilds (AlmaLinux, Rocky Linux, CentOS Stream, Oracle Linux) use their own package numbers: follow their advisories, not this table.
Careful: these are the FIRST fixed kernels for Copy Fail. The Dirty Frag fixes (and the Fragnesia fix on the newest streams) came later, so for a machine you are updating today, install the newest kernel your vendor offers.

Is my kernel patched?
Ubuntu:
   uname -r                                                                        # compare with the Ubuntu table above
   apt changelog linux-image-$(uname -r) | grep CVE-2026-31431                     # the changelog should mention the CVE
   pro fix CVE-2026-31431 --dry-run                                                # Ubuntu Pro client: says whether this machine is fixed
   dpkg -l kmod                                                                    # compare with the kmod versions above
Red Hat / RHEL:
   uname -r                                                                        # compare with the RHEL table above
   rpm -q --changelog kernel-$(uname -r) | grep CVE-2026-31431                     # the changelog should mention the CVE
   sudo dnf updateinfo list --cve CVE-2026-31431                                   # shows which advisory fixes it and whether it is installed
   sudo needs-restarting -r                                                        # says whether a reboot is still needed
Careful: rpm -q kernel and dpkg -l 'linux-image*' list INSTALLED kernels, including old ones you are not running. Only uname -r tells you what is actually running.

Common problems

The block file exists but the module still loads (Ubuntu): check modprobe -n -v algif_aead (it must print install /bin/false) and that the file ends in .conf and sits in /etc/modprobe.d/.
"install algif_aead /bin/false" did nothing on RHEL: expected. The code is built into the RHEL kernel, so modprobe cannot block it. Use the initcall_blacklist boot argument, or just patch.
I added the boot argument but /proc/cmdline does not show it: you have not rebooted, or you edited a different kernel entry. Re-run the grubby command with --update-kernel=ALL and reboot.
Something that used hardware or kernel crypto broke after the block: that is the side effect. Undo the block and patch instead. The fallback to userspace crypto is not guaranteed for every application.
I updated but uname -r shows the old kernel: you have not rebooted yet. The patch only counts once the new kernel is running.
The Ubuntu undo command says "No such file": Ubuntu's advisory uses two different file names (manual-disable-algif_aead.conf for the manual block, disable-algif_aead.conf for the kmod one). Run ls /etc/modprobe.d/ | grep -i algif and comment out or remove whichever file(s) are really there.
A cloud image shows a kernel name like 6.8.0-1057-aws: cloud kernels have their own fixed numbers. Do not compare them with the generic 6.8.0-117 line.

Tips

Patch and reboot beats blocking every time. Treat the block as a temporary bandage for hosts you cannot reboot yet, install the kernel, then remove the bandage.
Prioritise by who can run code: shared servers, container hosts, Kubernetes nodes, CI runners, jump boxes and anything with many SSH users come first.
Containers do not have their own kernel. Patching the host fixes the containers on it. Where you cannot block or patch, vendors also mention a seccomp profile that denies creating AF_ALG sockets; test it before rolling it out.
Two bugs, two mitigations: Copy Fail is algif_aead, Dirty Frag is esp4/esp6/rxrpc. Only the kernel update covers both.
Unprivileged users running su or sudo through unusual parent processes right after an SSH login is the kind of thing worth hunting for (Palo Alto's Unit 42 publishes example queries).
The corrupted copy lives in memory, so after mitigating or patching a machine you are worried about, drop the page cache or simply reboot: echo 3 | sudo tee /proc/sys/vm/drop_caches
Put the date and reason in a comment inside any block file you create. "Why does this box not do hardware crypto?" is a bad mystery at 2 a.m.
"Just four bytes" has never been comforting in security. It is exactly enough.

Sources (checked 2026-09-29)

Ubuntu advisory:                        https://ubuntu.com/blog/copy-fail-vulnerability-fixes-available
Ubuntu CVE tracker:                     https://ubuntu.com/security/CVE-2026-31431
Red Hat security bulletin (mitigation): https://access.redhat.com/security/vulnerabilities/RHSB-2026-002
Red Hat CVE data (fixed kernels):       https://access.redhat.com/security/cve/cve-2026-31431
Palo Alto Unit 42 technical analysis:   https://unit42.paloaltonetworks.com/cve-2026-31431-copy-fail/