Detect and mitigate CVE-2026-31431 (Copy Fail) on Linux systems.
Reason this release was yanked:
Recommended kernel upgrade commands were incorrectly generated for some distributions; upgrade hints are now plain-text guidance only. Use 0.0.3+.
Project description
copyfail-guard
A zero-dependency Python CLI that detects CVE-2026-31431 ("Copy Fail") on Linux systems and applies the modprobe-level mitigation. It supports Debian/Ubuntu, RHEL/Rocky/AlmaLinux, Fedora, and SUSE.
What is CVE-2026-31431?
A logic bug in the kernel algif_aead (AF_ALG AEAD socket) interface lets an
unprivileged local user perform a controlled 4-byte write into the page cache of
any readable file, leading to root privilege escalation. CVSS 7.8. The flaw has
been present since kernel 4.14 and was patched in stable releases starting in
April 2026.
What this tool does
- detect — combine four signals (kernel version,
/proc/modules,modules.builtin, modprobe blacklist) into one of six verdicts:patched,mitigated,vulnerable,unmitigable_builtin,not_applicable,unknown. - fix — write
/etc/modprobe.d/cve-2026-31431-copyfail-guard.confwithinstall algif_aead /bin/false, then runmodprobe -r algif_aead. It does not call your package manager — instead it prints the recommended kernel upgrade command for your distribution so you can review and run it yourself.
Install
pip install .
Or run from a checkout without installing:
PYTHONPATH=src python3 -m copyfail_guard detect
Usage
copyfail-guard [--json] [--dry-run] [--quiet] [--root PATH] [detect|fix]
detect (default)
$ copyfail-guard
[copyfail-guard] CVE-2026-31431 (Copy Fail) — VULNERABLE
Distribution: Ubuntu 24.04.1 LTS (debian family)
Kernel: 6.8.0-50-generic (branch 6.12, fixed at 6.12.85)
Module: algif_aead — loaded as .ko
Mitigation: none
Recommended actions:
1. Apply mitigation now:
sudo copyfail-guard fix
2. Upgrade kernel:
sudo apt-get update && sudo apt-get install --only-upgrade linux-image-generic ...
3. Reboot
fix
$ sudo copyfail-guard fix
[copyfail-guard] fix — OK
[ ok ] Pre-flight checks (Linux, host, root)
[ ok ] Wrote modprobe blacklist [/etc/modprobe.d/cve-2026-31431-copyfail-guard.conf]
[ ok ] Unloaded algif_aead [algif_aead]
[ ok ] Appended audit record [/var/log/copyfail-guard.log]
Next steps for a permanent fix:
1. sudo apt-get update && sudo apt-get install --only-upgrade linux-image-generic ...
2. Reboot
Always preview with --dry-run first.
JSON output
--json emits a structured document on stdout, suitable for jq/Ansible/SOAR pipelines:
$ copyfail-guard --json detect | jq .verdict
"vulnerable"
Exit codes
| Code | Meaning |
|---|---|
| 0 | safe — verdict is patched, mitigated, or not_applicable; or fix succeeded |
| 1 | vulnerable — verdict is vulnerable or unmitigable_builtin |
| 2 | error — could not determine state, refused due to preconditions, fix failed |
Mitigation reversal
To remove the mitigation after upgrading to a patched kernel:
sudo rm /etc/modprobe.d/cve-2026-31431-copyfail-guard.conf
sudo systemctl reboot
Notes
- Container hosts. copyfail-guard refuses to apply
fixfrom inside a container because/proc/modulesreflects the host but the container has no authority to load or unload modules. Run it on the host instead. - Built-in
algif_aead. Some custom kernels compilealgif_aeaddirectly into the image (CONFIG_CRYPTO_USER_API_AEAD=y). modprobe-level mitigation has no effect there; the only fix is upgrading the kernel. The detector reportsunmitigable_builtinin this case. blacklist algif_aeadvsinstall algif_aead /bin/false. Both block auto-loading viarequest_module, but the latter cannot be overridden with an explicitmodprobeinvocation. copyfail-guard installs the stronger form.- SELinux/AppArmor. Writes to
/etc/modprobe.d/inheritsystem_u:object_r:modules_conf_t:s0from the parent directory on RHEL; no relabel is needed. - initramfs/dracut.
algif_aeadis not included in the boot image on any major distribution, soupdate-initramfs -u/dracut -fis not required after installing the blacklist.
Development
PYTHONPATH=src python3 -m unittest discover tests
The test suite uses fixture filesystems under tests/fixtures/ so it runs on
macOS without needing real Linux. Each fixture contains a synthetic
/etc/os-release, /proc/modules, /sys/module/, and
/lib/modules/<rel>/{modules.dep,modules.builtin} tree.
License
Apache 2.0 — see LICENSE.
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file copyfail_guard-0.0.1.tar.gz.
File metadata
- Download URL: copyfail_guard-0.0.1.tar.gz
- Upload date:
- Size: 34.3 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
e6b98f6fb754bea65a50de27bcbb44da5822236f7c4c4a3850ae527d5a9e0c7d
|
|
| MD5 |
5043a1940cae8bc021ba88a6440fb814
|
|
| BLAKE2b-256 |
ba000cffb52b0fb323d3a13367e2c3bd60520f6dfa50add90dcd0faf2c4b018f
|
Provenance
The following attestation bundles were made for copyfail_guard-0.0.1.tar.gz:
Publisher:
python-publish.yml on ctzisme/copyfail-guard
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
copyfail_guard-0.0.1.tar.gz -
Subject digest:
e6b98f6fb754bea65a50de27bcbb44da5822236f7c4c4a3850ae527d5a9e0c7d - Sigstore transparency entry: 1436052998
- Sigstore integration time:
-
Permalink:
ctzisme/copyfail-guard@410c115a58440fbe36dae5146b5a81110fa081d8 -
Branch / Tag:
refs/tags/v0.0.1 - Owner: https://github.com/ctzisme
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
python-publish.yml@410c115a58440fbe36dae5146b5a81110fa081d8 -
Trigger Event:
release
-
Statement type:
File details
Details for the file copyfail_guard-0.0.1-py3-none-any.whl.
File metadata
- Download URL: copyfail_guard-0.0.1-py3-none-any.whl
- Upload date:
- Size: 28.2 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
0d125bd2fc3091e3f8ef39d51d28be83fddd723d2148e23fcb5ce7eb76818bd7
|
|
| MD5 |
1ff651453011d1e7fcd23be61b1e8ef5
|
|
| BLAKE2b-256 |
f8f41cf5e30a6dba1b0263cd1880182cbfb7a87a835b6be628f3325e7c48df33
|
Provenance
The following attestation bundles were made for copyfail_guard-0.0.1-py3-none-any.whl:
Publisher:
python-publish.yml on ctzisme/copyfail-guard
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
copyfail_guard-0.0.1-py3-none-any.whl -
Subject digest:
0d125bd2fc3091e3f8ef39d51d28be83fddd723d2148e23fcb5ce7eb76818bd7 - Sigstore transparency entry: 1436053006
- Sigstore integration time:
-
Permalink:
ctzisme/copyfail-guard@410c115a58440fbe36dae5146b5a81110fa081d8 -
Branch / Tag:
refs/tags/v0.0.1 - Owner: https://github.com/ctzisme
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
python-publish.yml@410c115a58440fbe36dae5146b5a81110fa081d8 -
Trigger Event:
release
-
Statement type: