flawopen.com/Teardowns/cve-2025-39682-linux-ktls-zero-length-record-mishandling
Linux CVE-2025-39682:kTLS 零长度记录处理缺陷
Linux kTLS 接收队列中的零长度非 DATA TLS 记录可能绕过每次 recvmsg 的记录类型检查。修复会检查已处理的记录类型,即使复制字节数为零。 Linux 的 CVSS 评估指出,可能后果包括内核堆数据泄露到用户空间、内存损坏以及远程导致内核崩溃;这是评估的影响,并不表示每台受影响系统都会出现所有结果。
CVSS 向量
CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H想象一个邮件分拣员,每个托盘只能放同一类别的信件。空信封仍然有类别,但旧分拣员通过信件数量决定是否换托盘。数量为零时,它忽略了信封类别,把下一种类型也放进同一托盘。内核修复会直接检查类别标记,即使信封里没有数据。
核心概念与专有名词
kTLS- 内核 TLS:Linux 可在内核中为已连接的 TCP 套接字处理 TLS 记录。
recvmsg()- 应用程序和 kTLS 接收路径使用的套接字接收系统调用。
TLS 内容类型- 用于标记记录类别的字段,例如应用数据或控制记录。
rx_list- 待处理接收记录队列,由后续 recvmsg 调用处理。
CWE-754- 对异常或特殊情况检查不当。NVD 列出
CWE-754,并注明来源为 CISA-ADP;Linux 的 CVE 记录本身未分配 CWE。
框架映射
- 本指南所述弱点的 CWE 参考: CWE-754
- CISA KEV — 收录日期 2026-09-18 — CVE-2025-39682
根本原因剖析 (Root Cause)
Linux kTLS 接收路径要求每次 recvmsg() 返回连续的 DATA 记录,或只返回一条非 DATA 记录。若 process_rx_list() 处理的第一条记录是零长度非 DATA 记录,它可能设置 TLS 类型,同时返回 err == 0。tls_sw_recvmsg() 将零赋给 copied,并使用 (copied && control != TLS_RECORD_TYPE_DATA) 作为停止条件的一部分。由于 copied 为零,已处理的类型被忽略,代码继续处理后续数据。上游补丁直接检查 control:若类型已报告且不是 DATA,就停止;零仍表示“尚未报告类型”。只有启用并使用 Linux 内核 TLS 接收路径(kTLS)的系统才受影响;这不是所有用户态 TLS 库解析器的问题。Linux 发布的 CVSS 3.1 向量为 9.8 Critical(AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H)。应根据实际 kTLS 使用情况和供应商内核状态评估风险。
攻击执行流程分解
kTLS 接收记录
应用程序使用启用了内核 TLS 接收的 TCP 套接字。
处理队列中的零长度非 DATA 记录
当 rx_list 的第一条记录没有负载时会触发此边界情况。处理可能报告类型,但返回复制字节数为零。
旧检查依赖已复制字节
由于 copied 为零,旧条件不会检查已处理类型是否为非 DATA。
接收循环跨越类型边界
后续数据可能在同一次 recvmsg 调用中处理,违反单一记录类型约束。 Linux 的 CVSS 评估指出,可能后果包括内核堆数据泄露到用户空间、内存损坏以及远程导致内核崩溃;这是评估的影响,并不表示每台受影响系统都会出现所有结果。
修复直接检查语义标记
修复后的条件会在 control 已设置且类型不是 DATA 时停止,与复制字节数无关。
源代码对比:漏洞与安全实现
摘自 net/tls/tls_sw.c,并非完整函数。上游将停止条件改为检查已报告的内容类型标记,而不是检查复制字节数。control == 0 表示尚未报告类型;非零的非 DATA 类型会终止本次 recvmsg 调用。这是上游补丁的精确逻辑更改。
源码摘录: 源代码:net/tls/tls_sw.c
copied = err;
if (len <= copied ||
(copied && control != TLS_RECORD_TYPE_DATA) || rx_more)
goto end;
copied = err;
if (len <= copied || rx_more ||
(control && control != TLS_RECORD_TYPE_DATA))
goto end;
工程与系统安全加固清单
- ✓盘点启用了 Linux kTLS 接收的工作负载;普通用户态 TLS 不代表自动受影响。
- ✓升级到包含修复的供应商内核包,并核对具体构建版本与安全公告。
- ✓保持约束:一次 recvmsg 调用只能处理连续 DATA 记录或一条非 DATA 记录,不能跨越类型边界。
- ✓运行或保留上游 kTLS 零长度记录回归测试;下游接收路径实现也应验证:空的非 DATA 记录不会导致同一次调用继续消费下一条记录。
- ✓区分“尚未观察到类型”和“复制了零字节”;检查
control等语义状态。 - ✓若暂不能修复,遵循供应商针对 kTLS 的缓解措施,并验证其对依赖内核 TLS 的工作负载的影响。