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

CVE-2025-39949 Linux内核qed驱动保护覆盖GRC转储缓冲区溢出漏洞

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

漏洞信息

漏洞编号
CVE-2025-39949
漏洞类型
缓冲区溢出(越界写入)
CVSS评分
5.5 中危
攻击向量
本地 (AV:L)
认证要求
低权限 (PR:L)
用户交互
无需交互 (UI:N)
影响产品
Linux内核qed驱动程序(qede以太网驱动、qedf存储驱动)

相关标签

缓冲区溢出Linux内核qed驱动qedeqedf拒绝服务内核panic本地提权CVE-2025-39949网络驱动

漏洞概述

CVE-2025-39949是Linux内核qed驱动程序中的一个高危本地漏洞,CVSS评分为5.5分,属于中危级别。该漏洞存在于保护覆盖(Protection Override)GRC转储路径中,当固件返回的GRC元素数量超过预期时,内核会尝试将数据写入先前通过kmalloc分配的转储缓冲区边界之外,从而触发内核页面错误并导致系统崩溃。

该漏洞影响使用qed驱动的多个子系统,包括qede以太网驱动和qedf(FCoE)存储驱动。当设备报告致命错误时,devlink健康报告机制会调用qed_dbg_protection_override_dump函数来收集调试数据。如果固件返回的元素数量异常,代码将越过分配的缓冲区边界进行写入,导致内核panic,错误信息为"BUG: unable to handle kernel paging request",崩溃地址恰好位于保护覆盖转储缓冲区结束位置之后。

此漏洞的攻击向量为本地(AV:L),需要低权限(PR:L),无需用户交互(UI:N),对机密性影响低(C:L),无完整性影响(I:N),但对可用性影响高(A:H)。攻击者可利用此漏洞触发系统拒绝服务(DoS),导致Linux系统崩溃。该漏洞已在Linux内核的多个稳定版本中得到修复,通过限制固件返回值到合法元素的最大数量来解决此问题。

技术细节

该漏洞的根本原因在于qed驱动程序中保护覆盖GRC转储路径缺少对固件返回元素数量的边界检查。具体技术细节如下:

1. **缓冲区分配机制**:当qed驱动初始化调试功能时,会为DBG_FEATURE_PROTECTION_OVERRIDE功能预先通过kmalloc分配一个固定大小的转储缓冲区(dump_buf),其大小由buf_size指定。

2. **漏洞触发路径**:当固件检测到致命错误并触发devlink健康报告机制时,系统会调用qed_dbg_protection_override_dump函数。在此过程中,固件会返回GRC元素的数量和内容。

3. **越界写入**:在qed_grc_dump_addr_range函数中,代码直接使用固件返回的元素数量进行循环写入操作,没有验证该数量是否在分配的缓冲区容量范围内。当固件返回的元素数量超过buf_size所能容纳的最大数量时,写入操作将越过缓冲区边界。

4. **崩溃触发**:可通过两条路径触发漏洞:
- qede以太网驱动路径:通过qede_sp_task → qed_report_fatal_error → devlink_health_report触发
- qedf存储驱动路径:通过qedf_rport_event_handler → qedf_cleanup_fcport → qed_fcoe_destroy_conn → qed_hw_err_notify触发

5. **修复方案**:通过在固件返回值上添加clamp操作,将其限制为固件应返回的最大合法元素数量,防止越界写入。

攻击链分析

STEP 1
步骤1:环境准备
攻击者需要在运行受影响Linux内核的系统上拥有本地低权限账户,且系统需配备使用qed驱动的QLogic/Marvell FastLinQ系列网卡(如QL41xxx、QL45xxx等)。
STEP 2
步骤2:触发固件致命错误
通过特定的网络操作或存储I/O操作触发qed设备的固件致命错误条件。对于qede路径,可通过网络异常触发;对于qedf路径,可通过FCoE连接异常(如qedf_cleanup_fcport)触发。
STEP 3
步骤3:调用devlink健康报告机制
固件致命错误触发qed_report_fatal_error,进而调用devlink_health_report和devlink_health_do_dump,进入调试数据收集路径。
STEP 4
步骤4:执行保护覆盖转储
系统调用qed_dbg_all_data → qed_dbg_feature → qed_dbg_protection_override_dump → qed_protection_override_dump,开始收集保护覆盖GRC转储数据。
STEP 5
步骤5:固件返回过多元素
固件在保护覆盖转储路径中返回远超预期的GRC元素数量,超过预先通过kmalloc分配的dump_buf缓冲区容量。
STEP 6
步骤6:越界写入导致内核崩溃
qed_grc_dump_addr_range函数使用固件返回的元素数量进行循环写入,缺少边界检查,导致写入越过dump_buf缓冲区边界,触发'BUG: unable to handle kernel paging request'内核panic,系统拒绝服务。

PoC / 利用代码

⚠️ 仅供安全研究
以下代码仅用于安全研究和授权测试,未经授权使用属于违法行为。
PoC
// CVE-2025-39949 PoC - Trigger qed protection override GRC dump buffer overflow // This PoC demonstrates how to trigger the vulnerability by forcing a firmware // fatal error report that invokes the protection override dump path with // excessive GRC elements. #include <stdio.h> #include <stdlib.h> #include <string.h> #include <fcntl.h> #include <unistd.h> #include <sys/ioctl.h> #include <errno.h> // Simulated malicious firmware response structure struct qed_dbg_protection_override_params { void *dump_buf; size_t buf_size; unsigned int num_grc_elements; void *grc_elements; }; /* * Trigger the vulnerability by sending an excessive number of GRC elements * to the qed protection override dump path. * * In a real scenario, this would involve: * 1. Loading the qed kernel module * 2. Triggering a firmware fatal error condition * 3. The firmware returns more GRC elements than the pre-allocated buffer can hold * 4. qed_grc_dump_addr_range writes past the buffer boundary -> kernel panic */ int trigger_protection_override_overflow(void) { struct qed_dbg_protection_override_params params; // Allocate a small buffer (simulating kmalloc'd dump_buf) params.buf_size = 4096; // Small pre-allocated buffer params.dump_buf = malloc(params.buf_size); if (!params.dump_buf) { perror("malloc failed"); return -1; } // Simulate firmware returning far more elements than buf_size can hold // This is the root cause of the vulnerability params.num_grc_elements = 65536; // Exceeds buffer capacity // In the vulnerable code path (qed_grc_dump_addr_range): // for (i = 0; i < params.num_grc_elements; i++) { // write_to_buf(params.dump_buf + offset, element[i]); // OOB write! // } printf("Triggering protection override dump with %u elements " "into %zu byte buffer\n", params.num_grc_elements, params.buf_size); printf("This would cause kernel panic: BUG: unable to handle " "kernel paging request\n"); free(params.dump_buf); return 0; } int main(int argc, char *argv[]) { printf("CVE-2025-39949 PoC - qed Protection Override GRC Dump Overflow\n"); printf("Affected: Linux kernel qed/qede/qedf drivers\n"); printf("Impact: Local denial of service via kernel panic\n\n"); trigger_protection_override_overflow(); printf("\nNote: Actual exploitation requires triggering a firmware\n"); printf("fatal error on a system with qed-based hardware (e.g.,\n"); printf("QLogic/Marvell FastLinQ adapters).\n"); return 0; }

影响范围

Linux kernel < 6.17 (修复提交25672c620421)
Linux kernel stable分支修复版本见git.kernel.org/stable/c/25672c620421fa2105703a94a29a03487245e6d6
Linux kernel stable分支修复版本见git.kernel.org/stable/c/56c0a2a9ddc2f5b5078c5fb0f81ab76bbc3d4c37
Linux kernel stable分支修复版本见git.kernel.org/stable/c/660b2a8f5a306a28c7efc1b4990ecc4912a68f87
Linux kernel stable分支修复版本见git.kernel.org/stable/c/70affe82e38fd3dc76b9c68b5a1989f11e7fa0f3
Linux kernel stable分支修复版本见git.kernel.org/stable/c/8141910869596b7a3a5d9b46107da2191d523f82

防御指南

临时缓解措施
在无法立即升级内核的情况下,建议采取以下临时缓解措施:1)限制对devlink接口的访问权限,仅允许root用户执行devlink相关操作;2)如果系统不使用FCoE存储功能,可通过blacklist机制禁用qedf驱动模块(echo "blacklist qedf" >> /etc/modprobe.d/blacklist.conf);3)监控kernel ring buffer(dmesg)中与qed相关的错误日志,及时发现异常;4)配置系统自动重启策略,以便在发生kernel panic后快速恢复服务;5)使用Linux内核的lockdown功能限制非特权用户对内核调试接口的访问。

参考链接

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