FlawOpen

flawopen.com/Teardowns/cve-2026-49878-android-wpa-supplicant-oob-write

● CVE-2026-49878 · CVSS 7.2 · Alta
Investigación · FlawOpen

CVE-2026-49878: escritura fuera de límites en el Wi-Fi de Android

El boletín Android de octubre de 2026 califica como Alta esta falla de ejecución remota en Wi-Fi. AOSP corrigió dos arrays int asignados por bytes en vez de elementos. El registro indica que se requieren privilegios de sistema.

💡 Explicación en Lenguaje Sencillo (ELI5)

Imagina una estantería para una caja por artículo, pero el encargado reserva solo un centímetro por caja. Las cajas sobresalen del espacio. En CVE-2026-49878, wpa_supplicant reservaba bytes según la cantidad de enteros y luego escribía enteros completos. El parche de Google reserva cada elemento con su tamaño correcto.

Conceptos Clave y Términos

wpa_supplicant
Componente Wi-Fi de Android que gestiona la autenticación inalámbrica y las interacciones 802.11.
Respuesta SCS
Trama de acción de respuesta del Stream Classification Service. El handler solo la procesa si hay una solicitud pendiente y coincide el token de diálogo.
Escritura fuera de límites (CWE-787)
Escritura más allá de la memoria reservada. Aquí se asignan bytes, pero se indexa como un array de elementos int.
os_zalloc / os_calloc
Ayudantes de asignación de wpa_supplicant. El parche usa cantidad y tamaño del elemento para reservar el array completo.
Nivel de parche de seguridad de Android (SPL)
Fecha que identifica el nivel de actualización instalado. Google indica que 2026-10-01 o posterior corrige el boletín; el fabricante controla la distribución.

Mapeos de marcos

  • Referencia CWE para la debilidad descrita en esta guía: CWE-787

Análisis de Causa Raíz

En wpas_handle_robust_av_scs_recv_action, scs_resp[0] y [1] son arrays int *. Antes de la corrección, os_zalloc(num_active_scs) reservaba solo ese número de bytes. El código guarda IDs y estados enteros por índice, por lo que necesita num_active_scs * sizeof(int) bytes. Las comprobaciones de solicitud pendiente, token coincidente, cantidad y longitud del frame limitan la entrada, pero no corrigen la unidad de asignación. El parche AOSP cambia ambas llamadas por os_calloc(num_active_scs, sizeof(int)). No se infiere ejecución de código controlada por el atacante a partir de esta escritura fuera de límites.

Flujo de Ataque Paso a Paso

Paso 1

Se despacha una trama de respuesta

La ruta Wi-Fi dirige Robust AV SCS Response al handler afectado. Es una ruta de red, pero las fuentes no demuestran que cualquier emisor no autenticado satisfaga todos los requisitos.

Paso 2

Se comprueban estado y límites

El handler exige una solicitud pendiente y token coincidente, y valida el recuento. El vector CISA-ADP de NVD indica AV:N/AC:L/PR:H/UI:N; conserva el requisito de privilegios altos.

Paso 3

Los enteros exceden la asignación en bytes

El código anterior reserva un byte por entrada y escribe valores int. Limitar la cantidad no aumenta la memoria asignada.

Paso 4

El parche de octubre corrige la asignación

El cambio de Google reserva num_active_scs elementos de sizeof(int) para ambos arrays. No inventes un payload ni afirmes que el diff demuestra ejecución arbitraria.

Código Fuente: Vulnerable vs. Seguro

El diff es el cambio de código publicado por AOSP en el commit d131540379d631d7dcb09b0169e4462bc65abcca, no pseudocódigo reconstruido. os_zalloc(n) usa n como tamaño en bytes; os_calloc(count, size) reserva y pone a cero la cantidad solicitada de elementos. La reparación corrige ambos arrays paralelos y conserva la limpieza existente ante un fallo de asignación.

IMPLEMENTACIÓN VULNERABLE
/* AOSP antes de la corrección: num_active_scs es un recuento de elementos,
 * pero os_zalloc lo recibe como una cantidad de bytes. */
scs_resp[0] = (int *) os_zalloc(num_active_scs);
if (!scs_resp[0])
    return;

scs_resp[1] = (int *) os_zalloc(num_active_scs);
if (!scs_resp[1]) {
    os_free(scs_resp[0]);
    return;
}
PARCHE SEGURO Y ROBUSTO
/* Corrección de AOSP: asignar un int completo para cada entrada. */
scs_resp[0] = os_calloc(num_active_scs, sizeof(int));
if (!scs_resp[0])
    return;

scs_resp[1] = os_calloc(num_active_scs, sizeof(int));
if (!scs_resp[1]) {
    os_free(scs_resp[0]);
    return;
}

Lista de Verificación de Seguridad para Ingeniería

Fuentes