一个函数换成另一个,两次,CVSS 评分 9.8
之前:kfree()。之后:kfree_rcu()。这就是 CVE-2026-98432 的全部修复内容,在两个不同的文件里的两个不同函数中重复出现。先看 CVSS 评分,这个漏洞听起来很抽象:9.8,严重,无需权限,无需用户交互。先看 diff,抽象感就消失了。这个漏洞就是一个函数名,在恰好两处被换成了错误的那个。
CVE-2026-98432 是 Linux 内核 IPv4 TCP 协议栈处理连接 IP 选项方式中的一个 use-after-free 漏洞,自 2015 年的一次提交起就已存在,现已在每个受维护的稳定分支中修复。[1] NVD 自己的 CNA 给出的评分是 9.8,向量为 AV:N/AC:L/PR:N/UI:N:远程、低复杂度、无需权限、无需用户交互。披露三周后,Red Hat 自己的公告仍未给出任何已修复的构建版本,Ubuntu 自己的跟踪页面仍将每个受支持的发行版标记为易受攻击或仍在处理中。[2][3] 据称,一个尚未公开发布的 Anthropic 研究模型在不到一小时内,把这个漏洞变成了一条可用的、零点击直达 root 的路径。[4] 关于这个说法,后面会仔细说明,因为网上流传的一个细节,其实并不是 Anthropic 真正说过的话。
我自己读了这个修复提交,而不是读别人对它的转述。直接访问 git.kernel.org 返回了 HTTP 403,于是我按哈希值,从 Greg Kroah-Hartman 在 GitHub 上维护的稳定树公开镜像中,读到了完全相同的那个提交。[5] 我没有在实验室里复现这个漏洞。这篇文章是从头到尾阅读一手资料写成的,不是靠跑一次漏洞利用,这个区别对后面的所有内容都很重要。
// The actual kfree -> kfree_rcu swap, per the fixing commit (dossier
// S2). Surrounding code is an illustrative reconstruction of shape, not
// a literal excerpt.
net/ipv4/af_inet.c, inet_sock_destruct():
- kfree(opt)
+ kfree_rcu(opt, rcu)
net/ipv4/tcp_ipv4.c, tcp_v4_reqsk_destructor():
- kfree(opt)
+ kfree_rcu(opt, rcu)“稍后释放”本该带来什么好处
这里有一个不变式,内核里大量网络代码都在不假思索地依赖它:处在 rcu_read_lock() 内部的读者,可以假定自己正在查看的内存依然存在,因为约定是写者会把真正的释放推迟到每个读者都确实完成之后。这就是 RCU(read-copy-update),是内核对一个难题的回答:怎样才能让读者快速、无锁地运行,同时写者仍然可以删除东西,而读者永远不会碰到已经消失的内存?
TCP request socket(内核在握手期间用来表示半开连接的对象)可以携带 IP 选项:由攻击者或网络提供、附加在 SYN 包 IP 头上的数据。内核把这些选项保存在一个指针后面(request socket 上是 ireq_opt,升级为完整 socket 后是 inet_opt),并在之后构建 SYN-ACK 或 ACK 时,在 ip_options_build() 内部读取它们。这次读取是在 RCU 保护下进行的。也必须如此:处理同一连接的重传 SYN 的第二个 CPU,完全可能在另一个 CPU 正在拆除这个连接的同一时刻,合法地处于这个函数内部。[1][5]
两个析构函数,一个捷径,零宽限期
有两处调用点打破了 RCU 所依赖的这份约定:net/ipv4/af_inet.c 中的 inet_sock_destruct(),以及 net/ipv4/tcp_ipv4.c 中的 tcp_v4_reqsk_destructor(),二者都用普通的 kfree() 立即释放了同一个 IP 选项指针,而不是用 RCU 延迟释放的 kfree_rcu()。[5] 普通的 kfree() 会在执行的瞬间就让内存可以被重新使用:没有宽限期,不等读者结束。任何仍处在 ip_options_build() 内部、正在读取那个析构函数刚刚释放的指针的 CPU,现在读到的,就是可能已经被重新分配并在它脚下被改写的内存。
读者那一侧用的是 RCU:开销小、无锁,而且只要释放被推迟,就能容忍并发的释放操作。写者那两处调用点却没有履行它们那一侧的承诺。这种不匹配,正是 WAF、身份验证检查,或任何应用层控制手段永远看不到的那类漏洞,因为它完全存在于内核自己的内存管理内部,深藏在析构路径里两次只有一行代码的函数调用之中。
// Illustrative timeline of the SYN-retransmit race (one of two trigger
// paths), reconstructed from the fixing commit's own description -- not
// a captured trace, and not exploit code.
CPU A (processing the connection) CPU B (retransmitted SYN)
---------------------------------- ----------------------------------
child socket created, inherits the
ireq_opt pointer -- not copied
tcp_v4_reqsk_destructor() runs:
kfree(ireq_opt) <-- freed now,
no grace period
still inside rcu_read_lock(),
ip_options_build() dereferences
the same pointer -- already
freed, possibly reused你重传的那个 SYN,或者你迁移的那个 request socket
这份修复提交描述了恰好两种落入这个窗口的方式,两种都不需要任何不寻常的条件。第一种:tcp_v4_syn_recv_sock() 把一个 request socket 的 IP 选项交给它新创建的子 socket,却没有先把这些选项复制一份,于是仍在处理同一连接重传 SYN(普通的 TCP 行为)的第二个 CPU,就可能在这些选项已经被释放之后读取它们。[1][5] 重传的 SYN 在真实网络上随时都在发生,所以攻击者不需要去制造这个条件,只需要掐准时机。
第二条路径还需要多满足一个条件:显式启用了 TCP request socket 迁移,无论是通过 net.ipv4.tcp_migrate_req=1,还是通过挂载了使用 SK_REUSEPORT_SELECT_OR_MIGRATE 的 BPF 程序。[5] 这在任何地方都不是默认设置。一旦启用,被克隆出来的 request socket 会和原来的共享同一个选项指针,同一个析构函数会在其中任意一个仍在使用它时,把它从脚下释放掉。如果你运行的是 IPv4/IPv6 混合协议栈,这里有一个细节很重要:修复提交指出,IPv6 不受这个重传竞争的影响,因为 IPv6 会复制一份自己 request socket 的选项,而不是共享它们。一个与 IPv6 迁移相关的问题被留给了另一个单独的补丁。[1][5] 这次修复只涉及 IPv4。
四十八分钟拿到指针,再五分钟拿到 root
这正是这个故事里真正引发病毒式传播的部分,值得把它讲得完全准确。Anthropic 自己发布的研究文章,署名 Frontier Red Team,称一个尚未发布的内部研究模型发现并串联了多个缺陷,构成了一次针对运行 multipath TCP 监听器的 Linux 服务器的远程零点击漏洞利用:无需凭据,无需用户交互,通过网络直接拿到 root。[4][6][7] 这篇文章按编号引用了 CVE-2026-98432。用 Anthropic 自己的话说,泄露一个内核指针用了 48 分钟,之后再用 5 分钟就实现了 shell 命令执行。[4]
有一个与这个说法一起流传的细节,其实并不在原文里。代号“Project Glasswing”没有出现在 Anthropic 文章的任何地方。它的来源是一条未经核实的二级线索,不是 Anthropic 自己的话,我不会在这里把它当成 Anthropic 确认过的名字来复述,因为 Anthropic 从未用过这个名字。真正得到独立印证的是:两家二级媒体都报道了相同的 CVE 编号、相同的 CVSS 评分,以及相同的 48 分钟加 5 分钟的时间线,而且两者都把 Anthropic 自己的文章作为来源。[6][7] 其中一家还加了一句话,值得在进入下一节之前停下来想一想:“这个 CVE 的公开记录描述的是一个 IPv4 TCP 的修复,而不是 multipath TCP 的修复,两者之间的联系仅仅来自 Anthropic 的这篇文章。”[7]
Red Hat 的公告从未提到 MPTCP。补丁也没有。
这句话就是整件事的全部关键,也正是大部分二手建议出错的地方。读一读内核自己的修复提交,它用纯粹的 IPv4 TCP 术语描述了两条触发路径——SYN 重传和 request socket 迁移——完全没有提到 Multipath TCP。[1][5] 再读一读 Red Hat 自己的公告 RHSB-2026-016,情况一样:“接受入站 TCP 连接的系统”被列为受影响群体,描述的是一个通用的竞争条件,前提条件、攻击向量或缓解建议里都没有 MPTCP。[2] 两份一手资料,都没有提到半个互联网都在建议大家关掉的那个东西。
这是我把这两份资料并排对照后得出的自己的解读,不是其中任何一份明确写出的句子,所以我要说得明白一点:MPTCP 监听器是可靠触发这个漏洞的一种方式,但它不是这个漏洞的决定性前提条件。如果某个具体演示过的漏洞利用确实选择了 MPTCP 作为入口点——按照上一节的说法,这是一个合理但仍未经证实的细节,来自某一个被报道的漏洞利用——那它告诉你的,是赢得这场竞争的一条实际路径,而不是这个漏洞本身真正需要什么。[4][7] 关闭 MPTCP(net.mptcp.enabled=0)只是去掉了这一种监听器类型作为触发面。它不会触及底层的那个 use-after-free,这个漏洞依然可以完全通过普通的、与 MPTCP 无关的 TCP 连接处理到达。
// What the vulnerability actually requires (b), versus what one
// reported demonstration used (c). Don't let (c) stand in for (b).
(b) Real preconditions, per the kernel's own commit and Red Hat's
advisory -- neither names MPTCP:
- A listener processing IPv4 TCP SYNs and retransmitted SYNs
(ordinary behavior, any TCP listener), OR
- Request-socket migration explicitly enabled
(net.ipv4.tcp_migrate_req=1, or a BPF
SK_REUSEPORT_SELECT_OR_MIGRATE program) -- not the default.
- Precise timing to win the race window.
- No credentials, no user interaction (PR:N/UI:N).
(c) What one reported demonstration reportedly used to trigger it
reliably:
- A reachable multipath TCP (MPTCP) listener.
Disabling MPTCP removes (c). It leaves (b) exactly where it was.内核里已经修复。大多数人在用的内核里还没有。
上游的修复已经落地,而且时间点非常精确:稳定分支从 5.10.272、5.15.223、6.1.190、6.6.159、6.12.113 和 6.18.56 开始就已经没有这个问题,7.2.10 也是,原始修复还被标记进了 mainline 7.3,这些全都与 NVD 自己来自厂商的数据完全一致。[1] 这是这件事里容易的那部分。你实际负载下运行的内核是否对得上这些版本号中的某一个,才是需要去核实、而不是靠假设的那部分。
Red Hat 自己的公告最后一次更新是在 2026-10-30,把这个漏洞评为“严重影响”,但没有给出任何已修复的构建版本、任何勘误,也完全没有给出 CVSS 评分。它只说 Red Hat“正在加快修复版本的发布”。[2] Ubuntu 自己的跟踪页面在本文写作时,把从 16.04 到 26.10 的每一个受支持发行版都标记为 Vulnerable 或 Vulnerable, work in progress。只有已经脱离标准支持的 14.04 被标记为不受影响。[3] 如果你还在等一个修复版本,Red Hat 提供的临时缓解措施是一条 nftables 规则,丢弃 IP 头中带有选项的入站 IPv4 TCP 包,这条规则不会影响普通的 TCP 层选项,并且被明确说明不能替代打补丁。[2]
还有一个数字在这里很重要,因为标题党们都在拼命渲染紧迫感:在本文写作时,CVE-2026-98432 并不在 CISA 的“已知被利用漏洞”目录中——用两种独立方式核实过——而且本文查阅过的任何来源都没有记录到已确认的在野利用。[8][9] 这和“可以放心往后排”不是同一个说法。一个无需身份验证、无需用户交互的 9.8 分漏洞,光凭这一点就足以带来真正的紧迫性。这才是诚实的尺度:在大多数发行版中严重且未修复,但尚未被确认正在遭到主动攻击。
Unaffected starting at (NVD vendor data, matches the kernel's own
per-branch fixes exactly):
5.10.272 5.15.223 6.1.190 6.6.159
6.12.113 6.18.56 7.2.10 (original fix tagged for mainline 7.3)
Distro status, read from each vendor's own tracker as of this writing:
Red Hat (RHSB-2026-016): Critical impact. No fixed version or
errata named. "Expediting the release
of fixes." Last updated 2026-10-30.
Ubuntu (security tracker): every supported release, 16.04-26.10,
Vulnerable or Vulnerable, work in
progress. Only 14.04 (out of support)
is clear.什么是已确认的,什么还只是网上的说法
关于这个 CVE,还有另外两件事在流传,我不打算对哪一件下结论,因为现有记录不允许我这么做。一种说法是,Red Hat 最初把这个漏洞评为 5.9 分,随后改为 8.1,再改为 9.8,这一步步上调部分归因于 Anthropic 披露的漏洞利用耗时。但 Red Hat 目前的公告根本没有显示任何评分、任何向量,也没有任何评分历史,所以这个从 5.9 到 8.1 再到 9.8 的具体说法,既无法用唯一可查的那份一手资料来确认,也无法用它来否定。[2]
另一件事是,是否真的存在一个公开的、能用的漏洞利用概念验证(PoC)。一条线索称,PoC 自 2026-10-29 起就已经出现在 GitHub 上;也有人说这个漏洞利用从未公开过。无论哪个方向,我都没有找到也没有验证过一个真正能用的 PoC 仓库。如果有人非常肯定地告诉你这两种说法里哪个是真的,向他要那个仓库,而不是那句断言。
这周真正该检查的事
按真正重要的顺序排列,不是按最适合当标题的顺序。
Patch and verify, in order:
[ ] Confirm the kernel actually RUNNING, not the changelog: 5.10.272 /
5.15.223 / 6.1.190 / 6.6.159 / 6.12.113 / 6.18.56 / 7.2.10 or later.
[ ] If your distro hasn't shipped a fixed build yet, check its own
tracker directly -- don't trust a blog post's snapshot of it,
this one included. Apply Red Hat's interim nftables rule in the
meantime: drop inbound IPv4 TCP with IP header length > 5.
[ ] Check net.ipv4.tcp_migrate_req. If it's 1, or a BPF
SK_REUSEPORT_SELECT_OR_MIGRATE program is attached, the second
trigger path is open regardless of MPTCP.
[ ] Disable MPTCP if you want to (net.mptcp.enabled=0) -- a
reasonable attack-surface reduction, but record it as exactly
that, not as the fix for this CVE.
[ ] Don't use CISA's KEV list as a signal of how exposed you are
here. As of this writing this CVE isn't on it, and that's a
statement about confirmed in-the-wild use, not about your risk.公告说的是“use-after-free”。diff 说的是具体在哪。
关于这个 CVE 的每一份公告都在说同样的三个词:use-after-free、内核、IPv4。它们任何一份单独拿出来,都不会告诉你真正的错误是两个析构函数在 kfree() 和 kfree_rcu() 之间选错了,也不会告诉你流传的那些关于 MPTCP 的建议,把某一次漏洞利用选中的那扇门,当成了整栋楼唯一的一扇门。是 diff 告诉了我这些。公告没有告诉我,也没打算告诉我:那本来就不是公告该做的事。
这正是我在安全代码审计里要找的那种缺口:不是看变更日志有没有写“已修复”,而是看那份真正的 diff 解决的是根本原因,还是只是某个人碰巧最先发现的那一条路径。如果你维护的 C 或 C++ 代码里存在同样的共享所有权、延迟生命周期模式——无论是通过 RCU 还是别的方式——并且想让人带着这个问题去读你的析构路径,这正是我做的那类审计。告诉我你在跑什么,我们来定范围。
参考来源
- [1] NVD:CVE-2026-98432 详情页
- [2] Red Hat:RHSB-2026-016 安全公告
- [3] Canonical(Ubuntu):CVE-2026-98432 安全跟踪页
- [4] Anthropic(Frontier Red Team):《Discovering vulnerabilities with Claude》
- [5] Linux 内核稳定树:修复提交,通过其公开 GitHub 镜像读取
- [6] AI Weekly:关于 Anthropic 链式漏洞利用说法的报道
- [7] The Hacker News:关于 Anthropic 链式漏洞利用说法的报道
- [8] CISA:已知被利用漏洞目录,筛选查询
- [9] CISA:已知被利用漏洞目录,JSON 数据源
需要在您自己的产品中检查这个问题吗?
安全代码审计想学会自己发现这类漏洞吗?
安全代码审计课程(一对一)