CVE-2025-39945CVE-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. **影响范围**:本地低权限用户可利用此漏洞进行权限提升,获取内核级执行权限,可能导致系统完全失陷。