FlawOpen

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

● CVE-2026-31431 · CVSS 7.8 · Alta
Investigación · FlawOpen

CVE-2026-31431: fallo Copy Fail del kernel Linux

Copy Fail es una escalada local de privilegios en la ruta AEAD de AF_ALG en Linux. Una optimización in-place confundió los mapeos de origen y destino; la corrección upstream restaura el procesamiento out-of-place y CISA incluye el CVE en KEV.[1], [2], [5]

💡 Explicación en Lenguaje Sencillo (ELI5)

Imagina a un bibliotecario que debe marcar una copia, pero un atajo lleva el lápiz al libro original. El atajo in-place permitía que una escritura para el resultado alcanzara otra página mapeada. La corrección procesa origen y destino por separado.[3], [8]

Conceptos Clave y Términos

AF_ALG
Interfaz de sockets criptográficos de Linux para procesos de usuario.[8], [3]
AEAD
Cifrado autenticado con datos asociados: cifra datos y autentica metadatos adicionales sin cifrarlos.[8]
algif_aead
Implementación AF_ALG para algoritmos AEAD, incluida la ruta vulnerable de origen y destino.[3]
Page cache
Caché en memoria del kernel para archivos; escribir en una página mapeada puede afectar lecturas antes de escribir en disco.[8]
CWE-1288 / CWE-669
NVD muestra CWE-1288 con redhat-SADP como fuente de la asignación; la página de Red Hat también indica esa CWE. La alerta del Centro Canadiense de Ciberseguridad clasifica el problema como CWE-669. Son clasificaciones atribuidas a fuentes distintas, no etiquetas intercambiables.[11], [7], [5], [9], [10]

Mapeos de marcos

Análisis de Causa Raíz

El cambio de 2017 72548b093ee3 introdujo una optimización in-place en algif_aead. El origen y el destino pueden proceder de mapeos distintos. authencesn puede escribir datos temporales fuera de la salida prevista; la lista de dispersión in-place podía alcanzar una página de caché de archivo proporcionada mediante splice(). El aviso CVE de Linux describe la reparación como volver al procesamiento out-of-place y conservar la copia de datos asociados. Requiere acceso local y que la ruta vulnerable esté habilitada. CVSS 7,8 (AV:L/AC:L/PR:L/UI:N/S:U/C:H/I:H/A:H); no es una entrada remota sin autenticación.[1], [3], [8], [7], [9], [10]

Flujo de Ataque Paso a Paso

Paso 1

Un proceso local alcanza la API

Un proceso local solicita una operación AEAD por AF_ALG, que se envía a algif_aead. Una petición remota por sí sola no alcanza esta interfaz local.[8], [7]

Paso 2

La ruta usa in-place

La implementación organiza origen y destino como si pudieran compartir páginas de forma segura, aunque sus mapeos difieran.[8], [3]

Paso 3

La escritura rebasa la salida

Durante authencesn, los datos temporales pueden salir de la región prevista y alcanzar la caché de un archivo pasado mediante splice().[8]

Paso 4

El kernel separa los mapeos

La corrección elimina la complejidad in-place innecesaria, copia los datos asociados y vuelve al procesamiento out-of-place.[1], [3]

Código Fuente: Vulnerable vs. Seguro

Resumen conceptual, no código literal del kernel ni un parche compilable. El aviso upstream indica que la corrección revierte en gran medida 72548b093ee3, salvo la copia de datos asociados, porque origen y destino proceden de mapeos distintos.[3], [2]

Fragmento de origen: crypto/algif_aead.c (_aead_recvmsg)

IMPLEMENTACIÓN VULNERABLE
/* Antes de la corrección: organizar la operación criptográfica en el mismo búfer. */
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);
    /* Construya y encadene una scatterlist TX para la etiqueta de autenticación. */
    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);
PARCHE SEGURO Y ROBUSTO
/* Después de la corrección: conservar una scatterlist de origen por solicitud. */
processed = used + ctx->aead_assoclen;
areq->tsgl_entries = af_alg_count_tsgl(sk, processed);
/* Asigne e inicialice areq->tsgl y, después, incorpore las páginas TX. */
af_alg_pull_tsgl(sk, processed, areq->tsgl);
tsgl_src = areq->tsgl;

/* Copie los datos asociados, pero mantenga separados el origen y el destino. */
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 Verificación de Seguridad para Ingeniería

Fuentes