flawopen.com/Teardowns/cve-2024-26585-linux-tls-tx-work-close-race
CVE-2024-26585: carrera al cerrar TLS en Linux
En kTLS de Linux, la finalización podía despertar sendmsg/recvmsg antes de encolar el trabajo TX. El parche lo programa primero.
Un trabajador avisa a un compañero «he terminado» antes de poner su última tarea en la cola compartida. En ese intervalo, el compañero puede cerrar el taller y cancelar las tareas pendientes; luego el trabajador añade una tarea demasiado tarde. La corrección del kernel encola el trabajo de transmisión TLS antes de señalar la finalización.
Conceptos Clave y Términos
kTLS- TLS en el kernel Linux, que procesa registros TLS en la ruta de red del kernel.
Finalización criptográfica asíncrona- Callback que se ejecuta cuando termina una operación asíncrona de cifrado TLS.
`complete()`- Primitiva de finalización de Linux que despierta a un hilo que espera a que termine una operación.
Trabajo TX diferido- Trabajo encolado del kernel que continúa la transmisión del registro TLS tras el cifrado.
Mapeos de marcos
- Referencia CWE para la debilidad descrita en esta guía: CWE-362
Análisis de Causa Raíz
En net/tls/tls_sw.c, tls_encrypt_done() podía llamar a complete() para el hilo que ejecutaba sendmsg()/recvmsg() antes de programar el trabajo TX diferido del registro situado al frente. El hilo despertado puede retornar y cerrar el socket mientras el callback aún va a encolar ese trabajo, creando una carrera entre el cierre del socket y la programación TX. El commit upstream e01e3934a1b2 invierte el orden: si el registro está al frente de ctx->tx_list, programa ctx->tx_work antes de llamar a complete(). El aviso describe una carrera; las fuentes citadas no respaldan las antiguas afirmaciones sobre MSG_ZEROCOPY, páginas de red liberadas, sobrescritura ni una corrección con refcount_inc_not_zero().
Flujo de Ataque Paso a Paso
1. Comienza la transmisión TLS
Un proceso usa la ruta de transmisión kTLS, donde el cifrado de registros puede finalizar de forma asíncrona.
2. El callback comprueba el orden
tls_encrypt_done() comprueba si el registro completado está al frente de ctx->tx_list.
3. El despertar compite con el cierre
Antes del parche, el callback podía despertar al hilo con complete() y encolar el trabajo TX después; el hilo podía cerrar el socket en medio.
4. El parche ordena la entrega
La corrección encola primero el trabajo TX diferido y después señala la finalización, para que el hilo no avance antes del encolado.
Código Fuente: Vulnerable vs. Seguro
// Orden relevante en net/tls/tls_sw.c antes de e01e3934a1b2
bool ready = false;
if (rec == first_rec)
ready = true;
if (atomic_dec_and_test(&ctx->encrypt_pending))
complete(&ctx->async_wait.completion);
if (!ready)
return;
if (!test_and_set_bit(BIT_TX_SCHEDULED, &ctx->tx_bitmask))
schedule_delayed_work(&ctx->tx_work.work, 1);
// Orden relevante en net/tls/tls_sw.c después de e01e3934a1b2
if (rec == first_rec) {
// Encole el trabajo de transmisión antes de despertar al hilo que lo envió.
if (!test_and_set_bit(BIT_TX_SCHEDULED, &ctx->tx_bitmask))
schedule_delayed_work(&ctx->tx_work.work, 1);
}
if (atomic_dec_and_test(&ctx->encrypt_pending))
complete(&ctx->async_wait.completion);
Lista de Verificación de Seguridad para Ingeniería
- ✓Actualiza a un kernel de distribución compatible que incluya el backport de
CVE-2024-26585; consulta el aviso del proveedor porque las ramas estables suelen recibir backports. - ✓Al revisar callbacks asíncronos, encola el trabajo siguiente antes de señalar la finalización si el hilo despertado puede cerrar el objeto compartido.
- ✓Sincroniza la cancelación o espera del trabajo durante el cierre para impedir que los callbacks encolen trabajo después del punto de cancelación.
- ✓Añade una prueba de concurrencia controlada que enfrente la finalización TLS asíncrona con el cierre del socket y verifique el orden del trabajo.
- ✓No supongas que
MSG_ZEROCOPYni el cifrado por hardware son requisitos; la descripción upstream habla de finalización criptográfica asíncrona y programación TX.