## https://sploitus.com/exploit?id=12FCA331-C34F-5CD8-A852-C88BEFC77FBF
# CVE-2026-31431 ("Copy Fail") โ Ansible Mitigation Recipe
[](https://github.com/USER/REPO/actions/workflows/ci.yml)
Detect and apply the kernel-cmdline mitigation for **CVE-2026-31431** ("Copy
Fail") across a Debian / Ubuntu / RHEL-family fleet using Ansible.
The CVE is a local privilege-escalation flaw in the Linux kernel's
`algif_aead` AF_ALG interface. Any unprivileged local user โ including
service accounts like `www-data`, `mysql`, or processes inside an RCE'd web
app โ can chain it to root in a few syscalls. The bug affects every major
distro shipped since 2017.
## What this recipe does
- **Detect** which hosts are missing the mitigation. Read-only by default.
- **Apply** the universal mitigation โ append `initcall_blacklist=algif_aead_init`
to the kernel command line โ when invoked with `-e apply_mitigation=true`.
- **Never auto-reboot.** Reboots are the operator's call.
The kernel cmdline blacklist works on **both** built-in (RHEL family) and
modular (Debian/Ubuntu) configurations, which the often-cited
`modprobe blacklist algif_aead` workaround does not.
## How the mitigation works
`algif_aead_init()` is the kernel function that registers the `aead` AF_ALG
algorithm with the crypto socket subsystem at boot. The cmdline parameter
`initcall_blacklist=algif_aead_init` instructs the kernel to skip that
initcall. The vulnerable code is still in the kernel binary, but
`socket(AF_ALG, ..., "aead")` returns `ENOENT`, so the exploit's first
syscall fails. No reachable surface, no privilege escalation.
Once vendors ship patched kernels and you reboot into them, the mitigation
is no longer needed and can be removed.
## Quick start
```bash
# 1. Detect (read-only) โ produces a per-host status report
ansible-playbook -i inventory check_cve_2026_31431.yml
# 2. Stage the mitigation on a single host first (no auto-reboot)
ansible-playbook -i inventory --limit \
-e apply_mitigation=true check_cve_2026_31431.yml
# 3. Reboot that host through your usual mechanism
# 4. Re-detect; confirm "Mitigation active: yes"
# 5. Roll out to the rest of the fleet in batches
```
A vulnerable host's report looks like this:
```
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
Host: 192.168.1.42
Distro: Ubuntu 24.04
Kernel: 6.8.0-60-generic
Mitigation active: no
Mitigation staged: no
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
โ ๏ธ 192.168.1.42: CVE-2026-31431 mitigation is NOT active.
```
## Reverting after a patched kernel ships
Out of scope for this recipe. Manual one-liners:
```bash
# Debian / Ubuntu
sudo sed -i 's/ initcall_blacklist=algif_aead_init//' /etc/default/grub
sudo update-grub
sudo reboot
# RHEL family
sudo grubby --update-kernel=ALL --remove-args="initcall_blacklist=algif_aead_init"
sudo reboot
```
## Won't-fail behavior
The detect path is strictly read-only (`uname`, slurp `/proc/cmdline`,
slurp `/etc/default/grub`, `grubby --info=ALL`). Probes use
`failed_when: false` so unexpected output never aborts the play.
`ignore_unreachable: true` means hosts you can't reach get a clear
"UNREACHABLE โ treat as VULNERABLE" warning instead of failing the run.
The apply path is wrapped in `block`/`rescue` so a single bad host never
stops the rest. The grub edit is idempotent and gated on
`mitigation_staged` so re-runs are no-ops.
## Testing
```bash
bash tests/run-checks.sh all
```
Stages: `lint` (yamllint + ansible-lint) โ `syntax`
(`ansible-playbook --syntax-check`) โ `dry-run` (executes the playbook in
`--check` mode against `localhost` with `-c local`, both detect and apply
paths). The same script is invoked by the GitHub Actions matrix across
`debian:12`, `ubuntu:22.04`, `ubuntu:24.04`, and `almalinux:9` containers
on every push and pull request.
What the dry-run does **not** verify:
- It does not modify grub, run `update-grub`, or trigger a reboot.
- `/proc/cmdline` inside a CI container shows the runner host's cmdline,
not the container's, so `mitigation_active` in CI output is meaningless.
CI proves the playbook *runs cleanly*; it does not prove a host is
mitigated.
See `tests/README.md` for more.
## Sources
- [Help Net Security โ CVE-2026-31431](https://www.helpnetsecurity.com/2026/04/30/copyfail-linux-lpe-vulnerability-cve-2026-31431/)
- [CloudLinux โ mitigation & fixed kernel versions](https://blog.cloudlinux.com/cve-2026-31431-copy-fail-mitigation-and-patches)
- [Ubuntu โ CVE-2026-31431](https://ubuntu.com/security/CVE-2026-31431)
- [Debian Security Tracker โ CVE-2026-31431](https://security-tracker.debian.org/tracker/CVE-2026-31431)
- [Tenable FAQ โ Copy Fail](https://www.tenable.com/blog/copy-fail-cve-2026-31431-frequently-asked-questions-about-linux-kernel-privilege-escalation)
- [CERT-EU SA 2026-005](https://cert.europa.eu/publications/security-advisories/2026-005/)
## Credits
Vulnerability discovered by **Taeyang Lee (Theori)** and weaponized into a
full exploit chain by the **Xint Code Research Team**, who deserve the
credit for making the security community pay attention. This recipe just
automates the mitigation they recommended.
## License
Beerware. See [`LICENSE`](LICENSE). TL;DR: do whatever you want with this;
if we ever meet, buy me a beer.
## Maintainer
[AESTECHNO](https://www.aestechno.com) โ Hugues Orgitello โ
electronics design house, Montpellier, France.