CVE-2025-39955CVE-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相关的请求套接字引用,防止悬挂指针和状态不一致问题。