Skip to main content

Detect and mitigate CVE-2026-31431 (Copy Fail) on Linux systems.

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.conf with install algif_aead /bin/false, then run modprobe -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 copyfail-guard

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. Update the kernel for a permanent fix:
       Update the kernel on this system to 6.12.85 or later (whatever your
       distribution ships once it has integrated the CVE-2026-31431 fix), then
       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 step for a permanent fix:
  Update the kernel to a CVE-2026-31431-patched version using your
  distribution's normal update mechanism, then reboot.

The fix is intentionally minimal: it writes a modprobe blacklist and unloads the module. It does not call your package manager. Updating the kernel itself is up to you — use apt/dnf/zypper (or your configuration management tool) however your environment normally handles security updates.

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 fix from inside a container because /proc/modules reflects 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 compile algif_aead directly 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 reports unmitigable_builtin in this case.
  • blacklist algif_aead vs install algif_aead /bin/false. Both block auto-loading via request_module, but the latter cannot be overridden with an explicit modprobe invocation. copyfail-guard installs the stronger form.
  • SELinux/AppArmor. Writes to /etc/modprobe.d/ inherit system_u:object_r:modules_conf_t:s0 from the parent directory on RHEL; no relabel is needed.
  • initramfs/dracut. algif_aead is not included in the boot image on any major distribution, so update-initramfs -u / dracut -f is 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


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

copyfail_guard-0.0.2.tar.gz (35.1 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

copyfail_guard-0.0.2-py3-none-any.whl (28.0 kB view details)

Uploaded Python 3

File details

Details for the file copyfail_guard-0.0.2.tar.gz.

File metadata

  • Download URL: copyfail_guard-0.0.2.tar.gz
  • Upload date:
  • Size: 35.1 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for copyfail_guard-0.0.2.tar.gz
Algorithm Hash digest
SHA256 a788fa973978a0cd8d573e373a6563be7322a63c852802dbe676e98856a8be54
MD5 18f20cc6359dfb4bf03f3bfa822067a4
BLAKE2b-256 1b602c4866d2c3c54bba0fe3c7808e00ec8312396d0d546299ec51f510d147dd

See more details on using hashes here.

Provenance

The following attestation bundles were made for copyfail_guard-0.0.2.tar.gz:

Publisher: python-publish.yml on ctzisme/copyfail-guard

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file copyfail_guard-0.0.2-py3-none-any.whl.

File metadata

  • Download URL: copyfail_guard-0.0.2-py3-none-any.whl
  • Upload date:
  • Size: 28.0 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for copyfail_guard-0.0.2-py3-none-any.whl
Algorithm Hash digest
SHA256 6c89b928ff50164da607c36b1df52b7eb8203addbafd6991a8b099ead33e8bcc
MD5 328745ba127ce623ffcf555ba828a54a
BLAKE2b-256 0fa2652651bde56a0228950d81f4f2e96967962fce6707af1626428a0ce77439

See more details on using hashes here.

Provenance

The following attestation bundles were made for copyfail_guard-0.0.2-py3-none-any.whl:

Publisher: python-publish.yml on ctzisme/copyfail-guard

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page