FlawOpen

flawopen.com/Teardowns/cve-2026-31431-linux-algif-aead-copy-fail

● CVE-2026-31431 · CVSS 7.8 · Alta
Pesquisa · FlawOpen

CVE-2026-31431: falha Copy Fail no kernel Linux

Copy Fail é uma elevação local de privilégios no caminho AEAD do AF_ALG no Linux. Uma otimização in-place confundiu os mapeamentos de origem e destino; a correção upstream restaura o processamento out-of-place, e a CISA inclui o CVE no KEV.[1], [2], [5]

💡 Explicação em Linguagem Simples (ELI5)

Imagine um bibliotecário que deve anotar uma cópia, mas um atalho leva o lápis ao livro original. O atalho in-place permitia que uma gravação destinada ao resultado atingisse outra página mapeada. A correção deixa de tratar os mapeamentos como equivalentes e processa origem e destino separadamente.[3], [8]

Conceitos Centrais e Termos

AF_ALG
Interface de sockets de criptografia do Linux para processos de usuário.[8], [3]
AEAD
Criptografia autenticada com dados associados: cifra dados e autentica metadados adicionais não cifrados.[8]
algif_aead
Implementação AF_ALG para algoritmos AEAD, incluindo o caminho vulnerável de origem e destino.[3]
Page cache
Cache em memória do kernel para arquivos; gravar em página mapeada pode afetar leituras antes da gravação em disco.[8]
CWE-1288 / CWE-669
O NVD lista CWE-1288 com redhat-SADP como fonte do mapeamento; a página da Red Hat também lista essa CWE. O alerta do Centro Canadense de Cibersegurança classifica o problema como CWE-669. São classificações atribuídas a fontes diferentes, não rótulos intercambiáveis.[11], [7], [5], [9], [10]

Mapeamentos de frameworks

Análise de Causa Raiz

A alteração de 2017 72548b093ee3 introduziu uma otimização in-place em algif_aead. Origem e destino podem vir de mapeamentos diferentes. O processamento authencesn pode gravar dados temporários fora da região de saída prevista; a lista de dispersão in-place podia atingir uma página de cache fornecida por splice(). O aviso CVE do Linux descreve a correção como retorno ao processamento out-of-place, mantendo a cópia dos dados associados. Exige acesso local e o caminho vulnerável habilitado. CVSS 7,8 (AV:L/AC:L/PR:L/UI:N/S:U/C:H/I:H/A:H); não é entrada remota sem autenticação.[1], [3], [8], [7], [9], [10]

Fluxo de Ataque Passo a Paso

Passo 1

Um processo local alcança a API

Um processo local solicita uma operação AEAD por AF_ALG, encaminhada a algif_aead. Uma solicitação remota isolada não alcança essa interface local.[8], [7]

Passo 2

O caminho usa in-place

A implementação organiza origem e destino como se pudessem compartilhar páginas com segurança, embora seus mapeamentos sejam distintos.[8], [3]

Passo 3

A gravação ultrapassa a saída

Durante authencesn, dados temporários podem ultrapassar a saída prevista e atingir uma página de cache associada a arquivo fornecido por splice().[8]

Passo 4

O kernel separa os mapeamentos

A correção remove a complexidade in-place desnecessária, copia os dados associados e retorna ao processamento out-of-place.[1], [3]

Código-Fonte: Vulnerável vs. Seguro

Resumo conceitual, não código literal do kernel nem patch compilável. O aviso upstream diz que a correção reverte em grande parte 72548b093ee3, exceto a cópia dos dados associados, pois origem e destino vêm de mapeamentos diferentes.[3], [2]

Trecho de origem: crypto/algif_aead.c (_aead_recvmsg)

IMPLEMENTAÇÃO VULNERÁVEL
/* Antes da correção: organize a operação criptográfica no mesmo buffer. */
rsgl_src = areq->first_rsgl.sgl.sg;

if (ctx->enc) {
    memcpy_sglist(areq->first_rsgl.sgl.sg, tsgl_src, processed);
    af_alg_pull_tsgl(sk, processed, NULL, 0);
} else {
    memcpy_sglist(areq->first_rsgl.sgl.sg, tsgl_src, outlen);
    /* Monte e encadeie uma scatterlist TX para a tag de autenticação. */
    areq->tsgl_entries = af_alg_count_tsgl(sk, processed, processed - as);
    /* ... */
}

aead_request_set_crypt(&areq->cra_u.aead_req, rsgl_src,
                       areq->first_rsgl.sgl.sg, used, ctx->iv);
PATCH SEGURO E ROBUSTO
/* Após a correção: mantenha uma scatterlist de origem por solicitação. */
processed = used + ctx->aead_assoclen;
areq->tsgl_entries = af_alg_count_tsgl(sk, processed);
/* Alocar e inicializar areq->tsgl e então incluir nele as páginas TX. */
af_alg_pull_tsgl(sk, processed, areq->tsgl);
tsgl_src = areq->tsgl;

/* Copie os dados associados, mantendo origem e destino separados. */
rsgl_src = areq->first_rsgl.sgl.sg;
memcpy_sglist(rsgl_src, tsgl_src, ctx->aead_assoclen);
aead_request_set_crypt(&areq->cra_u.aead_req, tsgl_src,
                       areq->first_rsgl.sgl.sg, used, ctx->iv);

Lista de Verificação de Segurança para Engenharia

Fontes