Skip to main content

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

Project description

copyfail-guard

PyPI Python License pylint

A zero-dependency Python CLI that detects and mitigates CVE-2026-31431 ("Copy Fail") on Linux. Works on Debian/Ubuntu, RHEL/Rocky/AlmaLinux, Fedora, and SUSE.

Background

CVE-2026-31431 is a logic bug in the algif_aead (AF_ALG AEAD socket) kernel interface that 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, present since kernel 4.14, patched in stable releases starting April 2026. A public PoC exists and the vulnerability is listed in CISA KEV.

What this tool does

Subcommand Action
detect Combines four signals (kernel version, /proc/modules, modules.builtin, modprobe config) into one of six verdicts
fix Atomically writes an install algif_aead /bin/false blacklist and runs modprobe -r algif_aead

fix is intentionally minimal — it does not call your package manager. Permanent remediation requires upgrading the kernel through your distribution's normal update mechanism.

Install

pip install copyfail-guard

Or run directly from a checkout without installing:

PYTHONPATH=src python3 -m copyfail_guard detect

Usage

copyfail-guard [--json] [--dry-run] [--quiet] [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, then reboot.

fix

Always preview with --dry-run before applying:

$ sudo copyfail-guard --dry-run fix
[copyfail-guard] fix — DRY RUN (no changes made)
  [dry] Would write modprobe blacklist  [/etc/modprobe.d/cve-2026-31431-copyfail-guard.conf]
  [dry] Would attempt to unload algif_aead (not currently loaded)
  [dry] Would append audit record  [/var/log/copyfail-guard.log]

$ 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.

JSON output

--json emits a structured document on stdout, suitable for jq, Ansible, or SOAR pipelines:

$ copyfail-guard --json | jq .verdict
"vulnerable"

$ copyfail-guard --json | jq '{verdict, kernel: .kernel.patched_threshold}'
{
  "verdict": "vulnerable",
  "kernel": "6.12.85"
}

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 — state could not be determined, precondition refused, or fix failed

Verdicts

Verdict Description
patched Running kernel is at or beyond the fixed version
mitigated Kernel is vulnerable but algif_aead is blocked by modprobe config
not_applicable Kernel is vulnerable but algif_aead is not present on this system
vulnerable Kernel is vulnerable, module is loadable, no mitigation in place
unmitigable_builtin algif_aead is compiled into the kernel image — modprobe mitigation has no effect; kernel upgrade required
unknown Kernel version could not be parsed or is outside the assessed range

Removing the mitigation

After upgrading to a patched kernel:

sudo rm /etc/modprobe.d/cve-2026-31431-copyfail-guard.conf
sudo reboot

Notes

Containers. fix refuses to run inside a container because /proc/modules reflects the host kernel but the container has no authority to load or unload modules. Run copyfail-guard on the host directly.

Built-in algif_aead. Some kernels compile algif_aead directly into the image (CONFIG_CRYPTO_USER_API_AEAD=y). modprobe mitigation has no effect in this configuration; the only remediation is a kernel upgrade. The tool reports unmitigable_builtin and skips the fix step.

blacklist vs install … /bin/false. Both directives block auto-loading, but install algif_aead /bin/false cannot be overridden by an explicit modprobe algif_aead invocation. copyfail-guard always installs the stronger form. If your system already has a plain blacklist directive, the tool reports mitigated but emits a note recommending the upgrade.

SELinux/AppArmor. Writes to /etc/modprobe.d/ on RHEL inherit system_u:object_r:modules_conf_t:s0 from the parent directory — no manual relabel is needed.

initramfs. algif_aead is not included in the boot image on any major distribution, so running update-initramfs -u or dracut -f is not required after installing the blacklist.

Development

git clone https://github.com/ctzisme/copyfail-guard
cd copyfail-guard
PYTHONPATH=src python3 -m unittest discover tests   # stdlib only, no pytest needed

The test suite uses fixture filesystems under tests/fixtures/ and runs fully on macOS without a real Linux environment. Each fixture provides a synthetic /etc/os-release, /proc/modules, 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.3.tar.gz (35.7 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.3-py3-none-any.whl (28.4 kB view details)

Uploaded Python 3

File details

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

File metadata

  • Download URL: copyfail_guard-0.0.3.tar.gz
  • Upload date:
  • Size: 35.7 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.3.tar.gz
Algorithm Hash digest
SHA256 a3b3261b875113c03f4ab11af75c50f97777da7d972c636d69a69baa7b6c5b7c
MD5 c9beacadd57bff32acca7de73698f820
BLAKE2b-256 4c9032b26e02b48882586f5cf515779a2a39c0f6c49e8cc1a0e174614e43fc5c

See more details on using hashes here.

Provenance

The following attestation bundles were made for copyfail_guard-0.0.3.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.3-py3-none-any.whl.

File metadata

  • Download URL: copyfail_guard-0.0.3-py3-none-any.whl
  • Upload date:
  • Size: 28.4 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.3-py3-none-any.whl
Algorithm Hash digest
SHA256 021e8bcc736e8616bb01530e37563761e75b6b60fa93e5a0bc381562fda71076
MD5 24a1b0b6bba3562788c458c940000f44
BLAKE2b-256 ea584fd023506b64d0cd9093d23ed86173ff436a39c15dcb345ff6dbd55cc4f0

See more details on using hashes here.

Provenance

The following attestation bundles were made for copyfail_guard-0.0.3-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