IPBUF安全漏洞报告
English
CVE-2025-71111 CVSS 4.7 中危

CVE-2025-71111 Linux kernel w83791d驱动TOCTOU竞态条件漏洞

披露日期: 2026-01-14
来源: 416baaa9-dc9f-4396-8d5f-8c081fb06d67

漏洞信息

漏洞编号
CVE-2025-71111
漏洞类型
TOCTOU竞态条件
CVSS评分
4.7 中危
攻击向量
本地 (AV:L)
认证要求
低权限 (PR:L)
用户交互
无需交互 (UI:N)
影响产品
Linux kernel hwmon w83791d driver

相关标签

Linux kernelTOCTOUw83791dhwmon竞态条件除零错误本地提权拒绝服务CVE-2025-71111

漏洞概述

CVE-2025-71111是Linux kernel中hwmon子系统w83791d驱动的一个中等严重性安全漏洞。该漏洞源于FAN_FROM_REG宏对参数进行多次求值,当在无锁上下文中操作共享驱动数据时,会产生Time-of-Check to Time-of-Use(TOCTOU)竞态条件。这种竞态条件可能导致除零错误,进而引发系统不稳定或拒绝服务。该漏洞需要本地低权限访问即可触发,无需用户交互。修复方案是将宏转换为静态函数,确保参数只求值一次,同时将store_fan_div函数中的最小限制计算移至更新锁内部,以保证读-修改-写序列在一致的数据上操作。

技术细节

在Linux kernel的w83791d硬件监控驱动中,FAN_FROM_REG宏定义存在设计缺陷。该宏定义为# define FAN_FROM_REG(val) ((val) && (val) != 255) ? (1350000U / (val)) : 0,当参数val是复杂表达式或包含副作用的操作时,会被多次求值。在多线程或中断上下文中,当代码以无锁方式访问共享的驱动数据时,会产生典型的TOCTOU问题:第一次求值检查val是否为非零和非255,第二次求值用于计算除法。如果在这两次求值之间val被其他执行流修改,可能导致val变为0,从而触发除零错误。攻击者可以通过精心设计的数据访问序列,在本地触发此竞态条件,造成系统崩溃或本地拒绝服务。修复措施包括:将FAN_FROM_REG宏转换为static inline函数以确保参数只求值一次;将store_fan_div中的最小限制计算移入锁保护区域,保证临界区内数据的一致性。

攻击链分析

STEP 1
步骤1
攻击者获得Linux系统的本地低权限访问权限
STEP 2
步骤2
攻击者识别w83791d硬件监控驱动的使用场景
STEP 3
步骤3
攻击者通过并发访问或中断触发TOCTOU竞态条件
STEP 4
步骤4
在FAN_FROM_REG宏的检查和使用之间,共享数据被修改导致除零
STEP 5
步骤5
除零错误导致内核崩溃或本地拒绝服务

PoC / 利用代码

⚠️ 仅供安全研究
以下代码仅用于安全研究和授权测试,未经授权使用属于违法行为。
PoC
// PoC concept for CVE-2025-71111 TOCTOU race condition // This demonstrates the race condition in w83791d FAN_FROM_REG macro #include <stdio.h> #include <pthread.h> #include <stdatomic.h> // Original problematic macro (evaluates val multiple times) #define FAN_FROM_REG(val) ((val) && (val) != 255) ? (1350000U / (val)) : 0 // Simulated shared driver data static volatile unsigned long shared_fan_value = 100; static _Atomic int race_triggered = 0; void* writer_thread(void* arg) { // Simulates another thread modifying the shared value for (int i = 0; i < 1000; i++) { // Race: modify value to 0 between check and use shared_fan_value = 0; // This can cause divide-by-zero shared_fan_value = 100; } return NULL; } void* reader_thread(void* arg) { // Simulates using the problematic macro for (int i = 0; i < 1000; i++) { unsigned long val = shared_fan_value; // Original macro evaluates 'val' multiple times: // First check: (val) && (val) != 255 // Second use: (1350000U / (val)) // If val changes between checks, race condition occurs unsigned int result = FAN_FROM_REG(val); // Check if we hit the race condition if (shared_fan_value == 0 && val != 0) { race_triggered = 1; printf("Race condition detected!\n"); } } return NULL; } int main() { pthread_t t1, t2; pthread_create(&t1, NULL, writer_thread, NULL); pthread_create(&t2, NULL, reader_thread, NULL); pthread_join(t1, NULL); pthread_join(t2, NULL); printf("PoC execution completed.\n"); printf("Fix: Convert macro to static function with pass-by-value semantics.\n"); return 0; } // Fixed version: // static inline unsigned int fan_from_reg(unsigned long val) // { // return (val && val != 255) ? (1350000U / val) : 0; // }

影响范围

Linux kernel w83791d driver < 3dceb68f6ad33156032ef4da21a93d84059cca6d
Linux kernel w83791d driver < 670d7ef945d3a84683594429aea6ab2cdfa5ceb4
Linux kernel w83791d driver < a9fb6e8835a22f5796c1182ed612daed3fd273af
Linux kernel w83791d driver < bf5b03227f2e6d4360004886d268f9df8993ef8f
Linux kernel w83791d driver < c8cf0c2bdcccc6634b6915ff793b844e12436680

防御指南

临时缓解措施
在官方补丁发布前,可通过以下措施缓解风险:1) 禁用不使用的w83791d硬件监控功能;2) 限制非特权用户对硬件传感器数据的访问;3) 使用SELinux或AppArmor限制对相关驱动设备的访问;4) 监控系统日志中的硬件监控错误信息。

参考链接

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