
BPF LSM blocker para CVE-2026-31431 (Copy Fail) — bloquea los binds de authencesn AF_ALG en tiempo de ejecución sin reiniciar
Prueba de concepto de mitigación en tiempo de ejecución para CVE-2026-31431 ("Copy Fail") — una escalada de privilegios en el kernel de Linux mediante la plantilla criptográfica authencesn en algif_aead.
A diferencia del bloqueo de módulos, esto no requiere reinicio. Un programa BPF LSM engancha socket_bind y bloquea todos los binds AEAD de AF_ALG — el subsistema explotado por Copy Fail. Esto evita bypasses mediante anidamiento de plantillas criptográficas (p. ej. pcrypt(authencesn(...))). Otros usos de AF_ALG (hash, skcipher) no se ven afectados.
Los intentos bloqueados se registran en tiempo real con PID, nombre del proceso y marca de tiempo.
CONFIG_BPF_LSM=y y lsm=bpf en los parámetros de arranquemake doctor # comprueba todos los requisitos previos
git clone https://github.com/atgreen/block-copyfail.git
cd block-copyfail
make ubi8-build
sudo ./block-copyfail
El bloqueador permanece activo hasta que pulses Ctrl-C, y luego se desengancha limpiamente.
Para compilar en tu propia máquina necesitas SBCL y Whistler (el compilador eBPF en Common Lisp):
git clone https://github.com/atgreen/whistler.git ~/git/whistler
make build
sudo ./block-copyfail
Compila dentro de un contenedor UBI8 para producir un binario que funcione en RHEL/CentOS/Alma/Rocky 8+, Fedora, Ubuntu 20.04+ y cualquier Linux con glibc 2.28 o superior. No se necesita SBCL ni Whistler en el sistema de destino — solo copia el binario y ejecútalo.
make ubi8-build
scp block-copyfail root@server:
ssh root@server ./block-copyfail
Produce un archivo .bpf.o estándar cargable por bpftool, libbpf o cualquier cargador BPF:
make elf
sudo mkdir -p /sys/fs/bpf/copyfail
sudo bpftool prog loadall block-copyfail.bpf.o /sys/fs/bpf/copyfail autoattach
Para desenganchar y eliminar:
sudo rm -rf /sys/fs/bpf/copyfail
Con el bloqueador ejecutándose en una terminal, dispara una prueba en otra:
python3 trigger-test.py
El script de prueba intenta un bind AEAD de AF_ALG (no se realiza ningún exploit).
Salida esperada en la terminal de prueba:
BLOCKED: aead/authencesn(hmac(sha256),cbc(aes)) — [Errno 1] Operation not permitted
BLOCKED: aead/gcm(aes) — [Errno 1] Operation not permitted
ALLOWED: hash/sha256
ALLOWED: skcipher/cbc(aes)
Salida esperada en la terminal del bloqueador:
Copy Fail blocker active — all AF_ALG AEAD binds blocked.
Other AF_ALG usage (hash, skcipher) unaffected.
Watching for blocked attempts. Press Ctrl-C to exit.
TIME PID COMMAND
---- --- -------
06:38:12 31337 python3
Sin el bloqueador ejecutándose, el script de prueba imprime ALLOWED para los cuatro algoritmos.
El programa BPF lee 7 bytes de struct sockaddr_alg de los argumentos de socket_bind mediante bpf_probe_read_kernel, comprueba salg_family == AF_ALG y salg_type == "aead", y devuelve -EPERM en caso de coincidencia. Esto bloquea todos los binds de algoritmos AEAD independientemente del anidamiento de plantillas. Los eventos se envían al espacio de usuario mediante un ring buffer.
Escrito en Whistler, un dialecto de Common Lisp que compila directamente a bytecode eBPF — sin C, clang ni LLVM.
MIT