
Una spiegazione strutturata di CVE-2026-31431 (Copy Fail), che collega le tre modifiche al kernel che hanno introdotto la vulnerabilità e ne hanno consentito lo sfruttamento.
Una falla logica in authencesn incatenata attraverso AF_ALG e splice() in una scrittura controllata di 4 byte nella cache delle pagine di qualsiasi file leggibile sul sistema. Nessuna condizione di gara, nessun offset, nessun payload compilato. Lo stesso script di 732 byte ottiene i privilegi di root su ogni distribuzione Linux dal 2017.
CVE-2026-31431 - Copy Fail è una falla logica nel template crittografico authencesn del kernel Linux. Consente a un utente locale non privilegiato di effettuare una scrittura controllata di 4 byte nella cache delle pagine di qualsiasi file leggibile sul sistema, senza modificare il file su disco.
Il bug non esiste in nessuno dei tre componenti individualmente. Emerge dalla loro interazione:``` 2011 ────────────────────────────────────────────────────────────────────── - authencesn added to the kernel (a5079d084f8b). - Uses the caller's destination scatterlist as scratch space. - Reorder ESN bytes before HMAC computation. - Only caller: internal xfrm layer. Harmless.
2015 ────────────────────────────────────────────────────────────────────── - algif_aead.c gains AEAD support with splice() path (104880a6b470). - splice() can deliver page cache pages to the TX scatterlist. - AF_ALG uses out-of-place operation: req->src != req->dst. - Page cache pages remain read-only. Not exploitable.
2017 ────────────────────────────────────────────────────────────────────── - In-place optimization in algif_aead.c (72548b093ee3). - Copies AAD+CT to RX buffer but chains authentication tag pages via sg_chain(). - Sets req->src = req->dst. - Page cache pages now reside in WRITABLE dst. - authencesn writes past boundary → page cache corruption.
2026 ────────────────────────────────────────────────────────────────────── - Copy Fail - CVE-2026-31431. Discovered by Theori / Xint Code. - Exploitable across all distros since 2017.
---
---
---
<div id='root-cause'/>
## ***🧬 Analisi della causa principale***
<div id='primitive'/>
### ***La primitiva AF_ALG + splice()***
AF_ALG (*[AF_ALG = 38](https://docs.kernel.org/crypto/userspace-if.html#user-space-api-general-remarks)*) è un tipo di socket che espone l'API crittografica del kernel allo spazio utente non privilegiato. Un processo non privilegiato può:
1. Aprire un socket AF_ALG / SOCK_SEQPACKET.
2. Eseguire bind() su qualsiasi template AEAD disponibile esposto dall'API crittografica del kernel.
3. Impostare una chiave crittografica tramite setsockopt(SOL_ALG, ALG_SET_KEY, ...) sull'algoritmo configurato.
4. Chiamare accept() per ottenere un socket operativo dedicato che gestisce le richieste di crittografia e decrittografia.
5. Inviare dati creati usando sendmsg() e ricevere il risultato elaborato tramite recvmsg(), interagendo completamente con il sottosistema crittografico del kernel.
È abilitato per impostazione predefinita nella configurazione del kernel di tutte le principali distribuzioni (CONFIG_CRYPTO_USER_API_AEAD=y).
**[splice(2)](https://man7.org/linux/man-pages/man2/splice.2.html)** trasferisce dati tra descrittori di file senza copiare - passa riferimenti alle pagine, non copie. Il flusso pertinente:```
open("/usr/bin/su") -> fd_file
pipe() -> pipe_rd, pipe_wr
# moves N bytes from the file into the pipe
# the pipe buffer now contains a reference to the same physical page in the page cache
splice(fd_file, pipe_wr, N)
# delivers that reference to the AF_ALG socket
# the TX scatterlist of algif_aead now points to the page cache page of /usr/bin/su
splice(pipe_rd, alg_fd, N)
The TX scatterlist of the AF_ALG socket contains direct references to the same physical pages used by the kernel for every read(), mmap(), and execve() of the file. No copy is involved.
Commit 72548b093ee3, algif_aead.c. Per la decifratura, l'implementazione:
In-place operation: RX SGL (req->dst): [ user buffer: AAD (copy) || CT (copy) ] --sg_chain--> [ Tag (page cache pages) ] req->src = req->dst = RX SGL
Result: page cache pages from /usr/bin/su are now part of the WRITABLE scatterlist passed to the crypto algorithm.
<div id='authencesn'/>
### ***La scrittura fuori dai limiti in authencesn***
authencesn è il wrapper AEAD del kernel utilizzato da IPsec con Extended Sequence Numbers (RFC 4303). IPsec utilizza numeri di sequenza a 64 bit:
- seqno_hi - 32 bit superiori (byte 0-3 del AAD)
- seqno_lo - 32 bit inferiori (byte 4-7 del AAD)
Solo seqno_lo viene trasmesso sul cavo; seqno_hi è contesto implicito. Per il calcolo HMAC, authencesn deve riorganizzare questi byte: seqno_hi all'inizio e seqno_lo alla fine dell'input di hash.