Proof of concept runtime mitigation for CVE-2026-31431 ("Copy Fail") — a Linux kernel privilege escalation via the authencesn cryptographic template in algif_aead.
Unlike module blacklisting, this requires no reboot. A BPF LSM program hooks socket_bind and blocks only the vulnerable authencesn algorithm. All other AF_ALG usage (dm-crypt, OpenSSL afalg engine, hash, skcipher) is unaffected.
Blocked attempts are logged in real time with PID, process name, and timestamp.
- Linux kernel 5.7+ with
CONFIG_BPF_LSM=yandlsm=bpfin boot parameters - SBCL 2.0+
- Whistler (Common Lisp eBPF compiler)
make doctor # check all prerequisites
git clone https://github.com/atgreen/block-copyfail.git
cd block-copyfail
make ubi8-build
sudo ./block-copyfail
The blocker stays active until you press Ctrl-C, then cleanly detaches.
make build
sudo ./block-copyfail
Build inside a UBI8 container to produce a binary that runs on RHEL/CentOS/Alma/Rocky 8+, Fedora, Ubuntu 20.04+, and any Linux with glibc 2.28 or newer. No SBCL or Whistler needed on the target system — just copy the binary and run it.
make ubi8-build
scp block-copyfail root@server:
ssh root@server ./block-copyfail
Produces a standard .bpf.o file loadable by bpftool, libbpf, or any BPF loader:
make elf
sudo mkdir -p /sys/fs/bpf/copyfail
sudo bpftool prog loadall block-copyfail.bpf.o /sys/fs/bpf/copyfail autoattach
To detach and remove:
sudo rm -rf /sys/fs/bpf/copyfail
With the blocker running in one terminal, trigger a test in another:
python3 trigger-test.py
The test script attempts an authencesn AF_ALG bind (no exploit is performed).
Expected output in the test terminal:
BLOCKED: [Errno 1] Operation not permitted
Expected output in the blocker terminal:
Copy Fail blocker active — authencesn bind blocked.
Other AF_ALG usage (dm-crypt, hash, skcipher) unaffected.
Watching for blocked attempts. Press Ctrl-C to exit.
TIME PID COMMAND
---- --- -------
06:38:12 31337 python3
Without the blocker running, the test script prints:
FAIL: bind succeeded (blocker not working)
The BPF program reads 34 bytes of struct sockaddr_alg from the socket_bind arguments via bpf_probe_read_kernel, checks salg_family == AF_ALG and salg_name starts with "authencesn", and returns -EPERM on match. Events are sent to userspace via a ring buffer.
Written in Whistler, a Common Lisp dialect that compiles directly to eBPF bytecode — no C, clang, or LLVM required.
MIT