flawopen.com/Teardowns/cve-2025-39682-linux-ktls-zero-length-record-mishandling
Linux CVE-2025-39682: fallo de registro vacío en kTLS
Un registro TLS no-DATA de longitud cero en la cola de recepción kTLS de Linux podía eludir la comprobación de tipo por recvmsg. La corrección comprueba el tipo procesado aunque no se hayan copiado bytes. La evaluación CVSS de Linux describe una posible exposición del heap del kernel al espacio de usuario, corrupción de memoria y bloqueos remotos del kernel; son consecuencias evaluadas, no una afirmación de que todos los sistemas afectados sufran cada resultado.
Vector CVSS
CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:HImagina un clasificador de correo que solo puede poner cartas de una categoría en cada bandeja. Un sobre vacío sigue teniendo categoría, pero el clasificador antiguo decidía cambiar de bandeja contando las cartas. Con cero cartas, ignoraba la categoría y mezclaba el tipo siguiente. La corrección del kernel comprueba el marcador de categoría aunque el sobre no tenga datos.
Conceptos Clave y Términos
kTLS- TLS del kernel: Linux puede procesar registros TLS en el kernel para un socket TCP asociado.
recvmsg()- Llamada de recepción de socket usada por la aplicación y la ruta de recepción kTLS.
Tipo de contenido TLS- Campo que clasifica el registro, como datos de aplicación o un registro de control.
rx_list- Cola de registros de recepción pendientes procesados por llamadas recvmsg posteriores.
CWE-754- Comprobación incorrecta de condiciones inusuales o excepcionales. NVD incluye
CWE-754y atribuye la clasificación a CISA-ADP; el registro CVE de Linux no asigna un CWE.
Mapeos de marcos
- Referencia CWE para la debilidad descrita en esta guía: CWE-754
- CISA KEV — añadido el 2026-09-18 — CVE-2025-39682
Análisis de Causa Raíz
La recepción kTLS de Linux debe devolver registros DATA contiguos o un solo registro no-DATA por llamada recvmsg(). Si process_rx_list() procesaba un registro inicial no-DATA de longitud cero, podía establecer el tipo TLS y devolver err == 0. tls_sw_recvmsg() copiaba ese cero en copied y usaba (copied && control != TLS_RECORD_TYPE_DATA) en la condición de parada. Como copied era cero, ignoraba el tipo ya procesado y continuaba con los datos siguientes. El parche upstream comprueba control directamente: si hay un tipo y no es DATA, se detiene; cero sigue siendo el marcador de “aún no se informó un tipo”. La exposición requiere que se habilite y utilice la recepción TLS del kernel Linux (kTLS); no es un defecto de todos los parsers TLS de espacio de usuario. El vector CVSS 3.1 publicado por Linux es 9,8 Crítico (AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H). Evalúe la exposición según el uso real de kTLS y el estado del kernel del proveedor.
Flujo de Ataque Paso a Paso
kTLS recibe registros
Una aplicación usa un socket TCP con la recepción TLS del kernel habilitada.
Se procesa un registro no-DATA vacío pendiente
El caso aparece cuando el primer registro de rx_list no tiene carga útil. El procesamiento puede informar un tipo y devolver cero bytes copiados.
La condición antigua depende de los bytes copiados
Como copied vale cero, la condición antigua no comprueba si el tipo procesado era no-DATA.
El bucle cruza el límite de tipo
Los datos siguientes pueden procesarse en la misma llamada recvmsg, contra la regla de tipo único. La evaluación CVSS de Linux describe una posible exposición del heap del kernel al espacio de usuario, corrupción de memoria y bloqueos remotos del kernel; son consecuencias evaluadas, no una afirmación de que todos los sistemas afectados sufran cada resultado.
La corrección comprueba el marcador semántico
La condición corregida se detiene si control indica un tipo no-DATA, sin depender de los bytes copiados.
Código Fuente: Vulnerable vs. Seguro
Fragmento de net/tls/tls_sw.c, no una función completa. Upstream cambió la condición de parada para usar el marcador del tipo informado, en lugar de comprobar si se copiaron bytes. control == 0 significa que no se informó ningún tipo; un valor no cero distinto de DATA detiene esta llamada recvmsg. Este es el cambio lógico exacto del parche upstream.
Fragmento de origen: net/tls/tls_sw.c — función tls_sw_recvmsg
copied = err;
if (len <= copied ||
(copied && control != TLS_RECORD_TYPE_DATA) || rx_more)
goto end;
copied = err;
if (len <= copied || rx_more ||
(control && control != TLS_RECORD_TYPE_DATA))
goto end;
Lista de Verificación de Seguridad para Ingeniería
- ✓Inventaríe las cargas que habilitan la recepción kTLS de Linux; TLS habitual en espacio de usuario no implica exposición automática.
- ✓Actualice al paquete de kernel del proveedor con la corrección y confirme la compilación en su aviso.
- ✓Mantenga la regla: cada llamada recvmsg procesa registros DATA contiguos o un registro no-DATA, sin cruzar tipos.
- ✓Ejecute o conserve la prueba de regresión upstream de kTLS para registros de longitud cero; las implementaciones downstream de recepción también deben comprobar que un registro no-DATA vacío no permita consumir el siguiente registro en la misma llamada.
- ✓Distinga “no se observó tipo” de “se copiaron cero bytes”; compruebe el estado semántico como
control. - ✓Si se retrasa el parche, siga la mitigación del proveedor para kTLS y valide el efecto en las cargas que requieren TLS en el kernel.