
Safe detection tooling for CVE-2026-31431 "Copy Fail" and CVE-2026-43284 "Dirty Frag" — a local privilege escalation in the Linux kernel's algif_aead module affecting all major distributions since 2017.
Safe detection tooling for two related Linux kernel local privilege escalation vulnerability families — Copy Fail (CVE-2026-31431) and Dirty Frag (CVE-2026-43284 / CVE-2026-43500) — both affecting all major distributions since 2017, both exploitable by any unprivileged local user, and both requiring independent mitigations.
These probes open no sockets and perform no crypto or network operations. Detection is based purely on kernel version, distro package metadata, module state, and active mitigation flags — all world-readable without
sudo.
Applying the Copy Fail mitigation does NOT protect against Dirty Frag. Both probes must be run and both mitigations applied independently.
.
├── cve-2026-31431-check.sh Copy Fail probe (all output modes)
├── copy_fail_userparameter.conf Zabbix agent UserParameter — Copy Fail
├── zabbix_template_copy_fail.yaml Zabbix 6.4 template — Copy Fail
├── copy_fail_auditd.rules auditd behavioral detection — Copy Fail
├── cve-2026-43284-check.sh Dirty Frag probe (all output modes)
├── dirty_frag_userparameter.conf Zabbix agent UserParameter — Dirty Frag
├── wazuh_sca/
│ └── copy_fail_sca.yml Wazuh SCA compliance policy
└── ansible/
└── copy_fall_scan.yml Fleet-wide Ansible scan playbook
The exploit requires this exact syscall chain:
socket(AF_ALG, SOCK_SEQPACKET, 0)
bind(fd, {alg_type="aead", alg_name="authencesn(hmac(sha256),cbc(aes))"})
accept(fd, ...)
splice(suid_binary_fd, op_fd) ← page cache fed into crypto subsystem
sendmsg / recvmsg ← 4-byte scratch write lands in page cache
None of these are touched by the probe. Detection is based on:
.ko on disk (auto-loadable)modprobe.d blacklist and initcall_blacklist cmdline flagchmod +x cve-2026-31431-check.sh
./cve-2026-31431-check.sh # human-readable
./cve-2026-31431-check.sh --json # machine-readable
./cve-2026-31431-check.sh --nagios # Nagios/Icinga/NRPE
./cve-2026-31431-check.sh --zabbix # integer 0/1/2 for Zabbix item
Exit codes: 0 = PATCHED or MITIGATED · 1 = VULNERABLE · 2 = UNKNOWN
The script compares against these thresholds automatically and sets verdict to PATCHED when the running package meets or exceeds the threshold.
On RHEL, AlmaLinux, Rocky Linux and derivatives, algif_aead is compiled into
the kernel. The modprobe.d workaround has no effect. Only
initcall_blacklist=algif_aead_init on the kernel cmdline works. The probe
detects this and warns explicitly.
grubby --update-kernel=ALL --args="initcall_blacklist=algif_aead_init"
reboot
Dirty Frag chains two in-place decrypt fast-path bugs discovered by Hyunwoo Kim (@v4bel), disclosed ~2026-05-07, one week after Copy Fail:
esp4, esp6); upstream fix f4c50a4034e6rxrpc); upstream fix aa54b1d27fe0The exploit attaches pipe pages from the /usr/bin/su page cache as paged
socket-buffer fragments, then drives in-place decryption with an attacker-chosen
key — writing arbitrary bytes directly into the cached copy of a setuid binary,
without touching the file on disk.
The Copy Fail mitigation (algif_aead blacklist) does NOT prevent Dirty Frag.
chmod +x cve-2026-43284-check.sh
./cve-2026-43284-check.sh # human-readable
./cve-2026-43284-check.sh --json # machine-readable
./cve-2026-43284-check.sh --nagios # Nagios/Icinga/NRPE
./cve-2026-43284-check.sh --zabbix # integer 0/1/2 for Zabbix item
The probe checks esp4, esp6, and rxrpc independently and reports separate
cve_43284_safe / cve_43500_safe booleans in JSON output.
esp4 and esp6 are the kernel-side ESP transforms used by IPsec (strongSwan,
Libreswan). Blacklisting them breaks IPsec tunnels. The probe detects active
IPsec usage via ip xfrm state and daemon detection, and adjusts the
remediation advice accordingly:
modprobe.d blacklist for all three modules.rxrpc separately if not needed):
# RHEL-family
sysctl -w user.max_user_namespaces=0
echo "install rxrpc /bin/false" >> /etc/modprobe.d/dirtyfrag.conf
# Ubuntu / Debian
sysctl -w kernel.unprivileged_userns_clone=0
echo "install rxrpc /bin/false" >> /etc/modprobe.d/dirtyfrag.conf
| Distro | CVE-2026-43284 | CVE-2026-43500 (rxrpc) |
|---|---|---|
| RHEL / Rocky / Alma 8.10 | 4.18.0-553.123.2.el8_10 | N/A — rxrpc not shipped on RHEL 8 |
| RHEL / Rocky / Alma 9.x | Pending |
For systems awaiting a patched kernel, apply the modprobe.d blacklist
immediately (taking the IPsec caveat into account).
AlmaLinux / RHEL 8 does not build the rxrpc module at all. The probe
auto-marks kernel_vuln_rxrpc=not_affected on RHEL/Rocky/Alma 8.x.
Deploy both probes on each monitored host:
mkdir -p /etc/zabbix/scripts
install -m 750 -o zabbix -g zabbix cve-2026-31431-check.sh /etc/zabbix/scripts/
install -m 750 -o zabbix -g zabbix cve-2026-43284-check.sh /etc/zabbix/scripts/
cp copy_fail_userparameter.conf /etc/zabbix/zabbix_agentd.d/
cp dirty_frag_userparameter.conf /etc/zabbix/zabbix_agentd.d/
systemctl restart zabbix-agent # or zabbix-agent2
Import zabbix_template_copy_fail.yaml via Configuration → Templates → Import.
UserParameter items provided:
The Copy Fail template includes HIGH trigger on status=1, WARNING on status=2.
No sudo required — every file read by both scripts is world-readable.
install -m 755 cve-2026-31431-check.sh /usr/lib/nagios/plugins/
install -m 755 cve-2026-43284-check.sh /usr/lib/nagios/plugins/
# NRPE — add to /etc/nagios/nrpe.cfg:
command[check_copy_fail]=/usr/lib/nagios/plugins/cve-2026-31431-check.sh --nagios
command[check_dirty_frag]=/usr/lib/nagios/plugins/cve-2026-43284-check.sh --nagios
# CheckMK local checks:
echo '#!/bin/bash
OUT=$(/usr/lib/nagios/plugins/cve-2026-31431-check.sh --nagios); RC=$?
echo "$RC CVE-2026-31431 - $OUT"' > /usr/lib/check_mk_agent/local/copy_fail
echo '#!/bin/bash
OUT=$(/usr/lib/nagios/plugins/cve-2026-43284-check.sh --nagios); RC=$?
echo "$RC CVE-2026-43284 - $OUT"' > /usr/lib/check_mk_agent/local/dirty_frag
chmod +x /usr/lib/check_mk_agent/local/copy_fail \
/usr/lib/check_mk_agent/local/dirty_frag
Detects an active exploit attempt in progress, complementing both static probes.
cp copy_fail_auditd.rules /etc/audit/rules.d/
augenrules --load
# Watch for unexpected AF_ALG callers:
ausearch -k copy_fail_af_alg --interpret | \
grep -v -E 'cryptsetup|veritysetup|systemd-crypt|kcapi'
Wazuh rule stubs (level 13 / 15) are embedded in the .rules file comments.
cp wazuh_sca/copy_fail_sca.yml /var/ossec/etc/shared/default/
/var/ossec/bin/agent_control -r -a
Results: Security → SCA → Filter by policy cve_2026_31431_copy_fail
ansible-playbook -i inventory/hosts ansible/copy_fall_scan.yml
# Limit to a subset:
ansible-playbook -i inventory/hosts ansible/copy_fall_scan.yml --limit webservers
Writes per-host JSON + summary.txt to /tmp/copy_fail_results/ on the
controller. The play exits non-zero if any host is VULNERABLE.
Copy Fail
Dirty Frag
| Copy Fail | Dirty Frag |
|---|
| CVE | CVE-2026-31431 | CVE-2026-43284 + CVE-2026-43500 |
| Module(s) | algif_aead | esp4, esp6, rxrpc |
| Introduced | Aug 2017 (kernel 4.14) | Jan 2017 / Jun 2023 |
| Mitigation | modprobe.d blacklist for algif_aead | modprobe.d blacklist for esp4/esp6/rxrpc |
| Probe script | cve-2026-31431-check.sh | cve-2026-43284-check.sh |
| Distro | Patched at | Advisory |
|---|
| RHEL / Rocky / Alma 8.10 | kernel-4.18.0-553.123.1.el8_10 | Rocky 2026-05-11 |
| RHEL / Rocky / Alma 9.7 | kernel-5.14.0-611.54.1.el9_7 | same |
| RHEL / Rocky / Alma 10.1 | kernel-6.12.0-124.55.1.el10_1 | same |
| Debian 11 (bullseye) | linux 5.10.251-3 | DLA-4560-1 |
| Debian 12 (bookworm) | linux 6.1.170-1 | DSA-6243-1 |
| Debian 13 (trixie) | linux 6.12.85-1 | DSA-6238-1 |
| Ubuntu 22.04 / 24.04 | No patched kernel yet — kmod mitigation via USN-8226-1 | USN-8226-1 |
| SLES 12 SP5 | kernel-default 4.12.14-122.299.1 | SUSE-SU-2026:1669-1 |
| SLES 15 SP5 | kernel-default 5.14.21-150500.55.144.1 | SUSE-SU-2026:1670-1 |
| SLES 15 SP6 | kernel-default 6.4.0-150600.23.92.1 | SUSE-SU-2026:1671-1 |
| SLES 15 SP7 | kernel-default 6.4.0-150700.53.40.1 | SUSE-SU-2026:1669-1 |
| SLES 16.0 | kernel-default 6.12.0-160000.29.1 | SUSE advisory |
| Pending |
| Debian / Ubuntu / SLES | Pending | Pending |
| Key | Type | Meaning |
|---|
copy_fail.status | int | 0=safe · 1=vulnerable · 2=unknown |
copy_fail.detail | str | Human-readable Copy Fail verdict |
dirty_frag.status | int | 0=safe · 1=vulnerable · 2=unknown |
dirty_frag.detail | str | Human-readable Dirty Frag verdict |
| Distro | Copy Fail | Dirty Frag |
|---|