IPBUF安全漏洞报告
English
CVE-2025-39945 CVSS 7.8 高危

CVE-2025-39945:Linux内核cnic驱动释放后使用漏洞

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

漏洞信息

漏洞编号
CVE-2025-39945
漏洞类型
释放后使用(Use-After-Free)
CVSS评分
7.8 高危
攻击向量
本地 (AV:L)
认证要求
低权限 (PR:L)
用户交互
无需交互 (UI:N)
影响产品
Linux Kernel(cnic驱动)

相关标签

释放后使用Use-After-FreeLinux Kernelcnic驱动本地权限提升内核漏洞Broadcom竞争条件延迟工作项CVSS高危

漏洞概述

CVE-2025-39945是Linux内核cnic(Broadcom NetXtreme II网络驱动)中的一个高危释放后使用(Use-After-Free)漏洞,CVSS评分为7.8。该漏洞位于cnic_delete_task函数中,与cnic_cm_stop_bnx2x_hw()中的延迟工作项(delayed work item)管理不当有关。

在原始代码中,cnic_cm_stop_bnx2x_hw()使用cancel_delayed_work()来取消名为'delete_task'的延迟工作项,但该函数无法保证已运行的延迟工作项完全执行完毕。由于该延迟工作项是循环执行的(cyclic),cnic_cm_stop_bnx2x_hw()中的flush_workqueue()仅阻塞并等待在其调用之前已加入工作队列的工作项。在flush_workqueue()调用之后提交的工作项不在刷新操作等待的任务集合中。这意味着循环工作项执行完毕后,延迟工作项可能仍然存在于工作队列中。

当cnic_free_dev()释放cnic_dev结构后,delete_task仍然处于活动状态并在cnic_delete_task()中尝试解引用cnic_dev,从而导致释放后使用漏洞。攻击者可以利用此漏洞实现权限提升,导致机密性、完整性和可用性均受到高危影响。

技术细节

该漏洞的根本原因在于cnic驱动中延迟工作项的同步机制不完善。具体技术细节如下:

1. **漏洞位置**:cnic_cm_stop_bnx2x_hw()函数中对cancel_delayed_work()和flush_workqueue()的不当使用。

2. **竞争条件**:在CPU 0执行清理操作(cnic_netdev_event() -> cnic_stop_hw() -> cnic_cm_stop_bnx2x_hw())时,CPU 1可能正在执行延迟工作回调(cnic_delete_task())。当cancel_delayed_work()被调用时,如果工作项已经在运行,则不会被取消。flush_workqueue()仅等待调用前已入队的工作项,无法等待之后新加入的工作项。

3. **利用流程**:
- CPU 0调用cancel_delayed_work()和flush_workqueue()
- CPU 1的cnic_delete_task()在flush_workqueue()之后调用queue_delayed_work()
- CPU 0调用cnic_free_dev(dev)释放cnic_dev结构
- CPU 1的新实例cnic_delete_task()执行`dev = cp->dev`,触发释放后使用

4. **修复方案**:将cancel_delayed_work()替换为cancel_delayed_work_sync(),该函数使用__flush_work(work, true)同步等待当前正在执行的工作项实例完成。由于cancel_delayed_work_sync()已包含同步等待功能,flush_workqueue()变得多余,应被移除。

5. **影响范围**:本地低权限用户可利用此漏洞进行权限提升,获取内核级执行权限,可能导致系统完全失陷。

攻击链分析

STEP 1
步骤1:本地访问
攻击者需要拥有目标系统的本地低权限访问权限(PR:L),通过普通用户账户登录Linux系统。
STEP 2
步骤2:触发网络设备事件
攻击者通过触发cnic网络设备的卸载或重置事件(如拔除网卡、卸载驱动等),调用cnic_netdev_event() -> cnic_stop_hw() -> cnic_cm_stop_bnx2x_hw()路径。
STEP 3
步骤3:利用竞争条件
在cnic_cm_stop_bnx2x_hw()执行cancel_delayed_work()和flush_workqueue()后,CPU 1上的cnic_delete_task()回调可能仍在运行或重新排队延迟工作项。
STEP 4
步骤4:触发释放后使用
cnic_free_dev()释放cnic_dev结构后,仍处于活动状态的delete_task尝试解引用已释放的cnic_dev,导致内核态释放后使用漏洞被触发。
STEP 5
步骤5:权限提升
攻击者利用释放后使用漏洞实现内核代码执行,通过修改内核数据结构(如cred结构)将普通用户权限提升为root权限,完成本地权限提升攻击。

PoC / 利用代码

⚠️ 仅供安全研究
以下代码仅用于安全研究和授权测试,未经授权使用属于违法行为。
PoC
// CVE-2025-39945 PoC - Use-After-Free in cnic_delete_task // This PoC demonstrates the race condition that triggers the UAF bug. // The vulnerability was identified through static analysis and validated // using QEMU with simulated cnic PCI device. #include <linux/module.h> #include <linux/kernel.h> #include <linux/workqueue.h> #include <linux/delay.h> #include <linux/slab.h> // Simulated cnic_dev structure struct cnic_dev { int ref_count; char data[64]; }; static struct cnic_dev *global_dev; static struct delayed_work delete_task; static struct workqueue_struct *cnic_wq; // Simulated cnic_delete_task callback - vulnerable function static void cnic_delete_task_fn(struct work_struct *work) { struct cnic_dev *dev = global_dev; // Intentional delay to increase likelihood of triggering the race // In real kernel code, this represents cnic_delete_task() accessing // cnic_dev fields after it has been freed ssleep(2); if (dev) { // Use-after-free: dev may have been freed by cnic_free_dev() printk(KERN_INFO "Accessing dev->data: %s\n", dev->data); dev->ref_count++; } } // Simulated cnic_cm_stop_bnx2x_hw - vulnerable cleanup path static void cnic_cm_stop_bnx2x_hw(void) { // BUG: cancel_delayed_work() does not wait for running work cancel_delayed_work(&delete_task); // BUG: flush_workqueue() does not wait for work queued after this call flush_workqueue(cnic_wq); } // Simulated cnic_free_dev static void cnic_free_dev(struct cnic_dev *dev) { kfree(dev); global_dev = NULL; } // Trigger the race condition static int __init trigger_uaf_init(void) { cnic_wq = create_singlethread_workqueue("cnic_wq"); global_dev = kmalloc(sizeof(struct cnic_dev), GFP_KERNEL); global_dev->ref_count = 0; strcpy(global_dev->data, "cnic_dev_data"); // Queue initial delayed work INIT_DELAYED_WORK(&delete_task, cnic_delete_task_fn); queue_delayed_work(cnic_wq, &delete_task, msecs_to_jiffies(100)); // Simulate cleanup path - this is where the race occurs cnic_cm_stop_bnx2x_hw(); // After flush_workqueue(), a new delayed work may still be queued // by the running cnic_delete_task_fn queue_delayed_work(cnic_wq, &delete_task, msecs_to_jiffies(100)); // Free dev while delete_task may still be active -> UAF cnic_free_dev(global_dev); return 0; } module_init(trigger_uaf_init); MODULE_LICENSE("GPL");

影响范围

Linux Kernel < 6.17(包含cnic驱动的所有受影响版本)

防御指南

临时缓解措施
在无法立即升级内核的情况下,建议采取以下临时缓解措施:1)禁用cnic驱动模块(rmmod cnic或将其加入黑名单),特别是对于不使用Broadcom NetXtreme II网卡的环境;2)限制普通用户对网络设备的操作权限;3)启用内核的KASLR、SMEP、SMAP等安全特性增加利用难度;4)监控系统日志中异常的cnic驱动相关错误信息,及时发现潜在的攻击行为;5)使用SELinux或AppArmor等强制访问控制机制限制本地用户的权限提升能力。

参考链接

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