
Analizza CVE-2026-31431, una vulnerabilità AF_ALG AEAD del kernel Linux, fornendo un rilevatore sicuro, un exploit LPE di laboratorio e un laboratorio kernel A/B basato su QEMU per la verifica.
algif_aead "Copy Fail": AnalisiRicerca di sicurezza su CVE-2026-31431 (CVSS 3.1 7.8 HIGH,
AV:L/AC:L/PR:L/UI:N/S:U/C:H/I:H/A:H): tre difetti di progettazione
componibili nella catena AEAD di AF_ALG si combinano in una
scrittura deterministica e senza race condition di 4 byte nella page cache a qualsiasi offset di qualsiasi file leggibile — la copia su disco rimane pulita, quindi i checksum su disco non vedono nulla.
L'exploit pubblico ("Copy Fail", Theori/Xint) lo trasforma in root
locale (LPE) con 732 byte di Python; il bug è rimasto in ogni kernel
dal 2017 al 2026.
72548b093ee3 (2017) ha fatto sì che _aead_recvmsg decifrasse in-place,
concatenando le pagine tag della richiesta nell'SGL di destinazione scrivibile.splice(file → pipe → socket) alimenta quegli slot tag con le
pagine della page cache di qualsiasi file leggibile (zero copy).authencesn scrive il suo scratch ESN di 4 byte — il valore viaggia in
del payload sendmsg — esattamente a
, cioè il primo byte del tag: l'offset del file da te scelto. Viene eseguito della verifica del tag, quindi anche una
richiesta effettua la scrittura.AAD[4..8)dst[assoclen + cryptlen]-EBADMSG| Affermazione | Evidenza |
|---|---|
| Causa root derivata dai commit di fix e dai sorgenti del kernel, non da blog | finding-sheet |
| Decodifica del PoC pubblico verificata end-to-end rispetto alla sequenza di syscall | finding-sheet |
| Kernel A/B di laboratorio con delta = esattamente il commit di fix, entrambi avviati | lab/scripts/build.sh + lab/out/ab-diffstat.txt |
Il kernel vulnerabile esegue la decifratura AEAD authencesn tramite AF_ALG (smoke) | lab/scripts/run.sh vuln → SMOKE=ok |
Revert senza companion causa panic in crypto_authenc_esn_decrypt (finding originale) | lab/scripts/run.sh patched → NULL deref, riproducibile |
| Detector sicuro: VULNERABLE su vuln (la scrittura avviene nonostante EBADMSG, il disco rimane CLEAN), NOT-DETECTED su fix completo | poc/detector.c nel lab → righe DETECTOR-RESULT |
| Chiusura LPE in laboratorio: uid 1000 modifica 4 byte della page cache di un binario SUID e legge il flag root-only; copia su disco dimostrata integra tramite lettura debugfs a livello di blocco | poc/lpe.c + lab/rootfs/tools/secretgate.c → LPE-RESULT: ROOT-FLAG-CAPTURED, DISKCLEAN=ok |
| Riproduzione della scrittura pubblica nella page cache in un lab isolato, con attribuzione | output del detector sopra + lab README |
| Stress SGL: 5 forme su entrambi i kernel — nessun crash, nessun hang del kernel (negativo onesto) + due peculiarità contrattuali AF_ALG documentate | poc/sgl-stress.c nel lab → righe SGL-STRESS |
# compila i tre kernel + strumenti + disco di probe in Docker (~15 min alla prima esecuzione)
lab/scripts/build.sh
# avvia l'oracolo A/B/C (QEMU in Docker, KVM se disponibile)
lab/scripts/run.sh vuln # DETECTOR VULNERABLE + LPE ROOT-FLAG-CAPTURED + DISKCLEAN=ok
lab/scripts/run.sh patchedfull # DETECTOR NOT-DETECTED + LPE NOT-VULNERABLE
lab/scripts/run.sh patched # NULL deref di authencesn (gap del fix companion)
La catena completata di scrittura nella page cache segue l'approccio pubblicato da
Theori / Xint Code ("Copy Fail", i reporter accreditati) con
attribuzione — vedi la sezione prior-art del finding-sheet. Lavoro originale in questo repo: la mappa della meccanica ancorata ai commit di fix, il finding della serie di fix incompleta (il panic di authencesn da revert senza companion e la sua finestra di rilascio stabile), il detector differenziale sicuro page-cache-vs-disco che non tocca mai file che non possediamo, la chiusura LPE in laboratorio contro un target SUID costruito ad hoc
(secretgate — nessun binario del mondo reale viene mai preso di mira), l'esplorazione degli edge SGL (risultato negativo onesto più due peculiarità contrattuali AF_ALG documentate) e l'attribuzione verificata dei branch di tutti gli otto commit di fix.
| Doc | Cosa contiene |
|---|---|
| docs/finding-sheet.md | Scheda tecnica di una pagina: versioni, CVSS, causa root, commit di fix, superficie d'attacco |
| docs/report-ptes.md | Report strutturato PTES (7 fasi) con evidenze di laboratorio |
| docs/research-writeup.md | La narrazione dell'indagine — metodologia, vicoli ciechi, lezioni portabili, confronto con lavori precedenti |
docs/ finding sheet · report PTES · writeup di ricerca
poc/ detector.c (oracolo sicuro) · lpe.c (LPE in laboratorio) · sgl-stress.c (esplorazione SGL)
lab/ laboratorio kernel QEMU: 5.15.203 ± fix (A/B) + post-companion 5.15.y (C)
lab/rootfs/ secretgate.c — target SUID costruito ad hoc (l'unica cosa mai attaccata)
72548b093ee3 "crypto: algif_aead - copy AAD from src to dst" (2017)a664bf3d603d "crypto: algif_aead - Revert to operating out-of-place"
(+ 8 backport stabili — vedi finding-sheet)Artefatto di ricerca educativa. Eseguire solo contro sistemi che possiedi o per cui sei esplicitamente autorizzato a fare test. La vulnerabilità è stata corretta — esegui un kernel aggiornato dai branch stabili del 2026 o successivi.