Copy Fail & Dirty Frag: Anatomy of the 2026 Linux Kernel Page Cache Write Vulnerabilities — Di 12 Mai 2026

你好,世界!

2026年春季,作为 自由软件 的 Linux 内核安全领域接连曝出两个影响广泛的本地提权漏洞——Copy Fail(CVE-2026-31431)与 Dirty Frag(CVE-2026-43284 / CVE-2026-43500)。它们属于同一类漏洞家族,攻击思路一脉相承,但利用路径和影响范围各有不同。更重要的是,两者都因“零拷贝”性能优化而起,最终成为攻击者手中稳定的提权武器。

Copy Fail:从 AF_ALG 到页缓存写入

Copy Fail 是2026年4月29日公开披露的一个高危漏洞,其发现者为安全研究团队 Theori。漏洞存在于内核加密算法接口`algif_aead`中,这是内核提供用户态程序访问对称加密、认证加密等功能的 AF_ALG 套接字类型的一部分。

这个漏洞的根源可以追溯到2017年7月的一次“优化”。当时内核开发者提交了编号为`72548b093ee3`的补丁,将 AEAD(带关联数据的认证加密)操作改为“就地”(in-place)处理模式。所谓就地处理,就是不再为加密操作分配独立的输出缓冲区,而是直接在输入缓冲区上完成运算。这在内存分配上确实更高效——少了一次数据拷贝和一块临时内存。

但问题在于,`algif_aead`的输入数据来源并不总是内核私有内存。攻击者可以使用`splice()`系统调用,将一个只读文件的页缓存页面直接“钉”进加密操作的发送缓冲区。这些页缓存页面本该是只读的,现在却被链入了可写的目标散列表。

真正的“爆炸点”发生在`crypto_authenc_esn_decrypt()`函数中。这个函数在处理特定格式的 AEAD 解密时,需要将4字节的序列号高位写入输出缓冲区的末尾。由于输入和输出指向了同一块内存,这4字节写操作就直接落到了那个通过`splice()`引入的只读文件页缓存上。认证检查在后面才执行,无论结果是成功还是失败,那4字节已经写进去了。

换言之,攻击者对任意一个可读的文件(比如`/usr/bin/su`这个 setuid 程序),获得了4字节的任意写原语。4字节看着很少,但足以改写 ELF 程序的关键元数据,或者打乱指令流的跳转地址。更致命的是,这种改写发生在内存页缓存中,磁盘上的原始文件完好无损,因此基于文件哈希的完整性检测工具完全无法发现攻击痕迹。

攻击者只需要通过 unshare 创建用户命名空间(以获得必要的网络能力),然后用 vmsplice 和 splice 构建 payload,触发解密,就能逐段改写目标文件的内存副本。Theori 发布的利用代码只有732字节,稳定可靠,无需竞争条件,也不需要针对不同内核版本调整偏移量。

受影响的内核版本从4.14开始,一直到6.18.22、6.19.12及7.0之前的版本。换言之,过去近九年里发布的大部分 Linux 发行版都处于风险之中。

Dirty Frag:网络协议栈的“化整为零”

Copy Fail 公开仅一周后,2026年5月7日,安全研究员 Hyunwoo Kim(@v4bel)披露了一套更复杂的漏洞组合,命名为 Dirty Frag。这个名称既有对“Dirty Pipe”系列的致敬,也暗示了攻击对象的特殊性:网络数据包的“碎片”(fragment,即 skb 非线性区的 frag 数组)。

Dirty Frag 实际上包含两个独立的子漏洞,分别针对不同的内核子系统:CVE-2026-43284位于 IPsec ESP(封装安全载荷)处理路径中的 xfrm 模块;CVE-2026-43500位于 AFS 分布式文件系统使用的 RxRPC 认证路径中。

两个漏洞的核心思路与 Copy Fail 完全相同:利用`splice()`将只读文件的页缓存页面送入内核网络栈的某个缓冲区,然后在某处“就地”写操作中污染该页面。但它们的触发方式和攻击目标各有特色。

xfrm-ESP 变体(CVE-2026-43284)是 Dirty Frag 的“主力”。

它利用 ESP 协议解密过程中的就地操作漏洞。问题出现在`esp_input()`函数:当传入的 skb(socket buffer)是非线性的(即有 frag 但无 frag_list),代码直接跳过了本该执行的`skb_cow_data()`,跳过了写时复制,转为对原始 frag 中的页面进行就地解密。

如何将文件页缓存变成网络数据包的一个“碎片”?攻击者构造一个伪造的 ESP 头(24字节),用 vmsplice 写入管道,再用 splice 将目标文件(还是`/usr/bin/su`)的页缓存钉进管道的下一个槽,最后再次使用 splice 将这个管道发给一个 UDP 套接字。接收端配置了 UDP_ENCAP_ESPINUDP,会触发`esp_input`。文件页缓存就这样成了待解密的“碎片载荷”。解密时,4字节的写操作精准落在目标文件页缓存的指定偏移上。

攻击者通过注册 XFRM SA(安全关联)时自由设置`seq_hi`字段,事实上可以完全控制写入的4字节内容。这意味着攻击者不仅能在任意偏移写入任意4字节,而且可以反复进行。最终效果是:将`/usr/bin/su`内存副本的前192字节替换成一个迷你 root shell ELF,然后执行`su`即可获得 root shell。

需要`CAP_NET_ADMIN`能力?攻击者只需用`unshare(CLONE_NEWUSER | CLONE_NEWNET)`创建一个用户命名空间,在里面就拥有完整的 root 能力。

RxRPC 变体(CVE-2026-43500)则是“补位选手”。

它利用 AFS/RxRPC 协议的数据包认证流程中的就地解密漏洞。`rxkad_verify_packet_1()`函数对 skb 前8字节做就地 PCBC 解密,通过`skb_to_sgvec()`将 frag 直接转为散列表,文件页缓存再次成为 src/dst,写操作落地。

这个变体的“写”不能完全控制内容(解密结果取决于文件原有内容与攻击者注册的会话密钥),但攻击者可以通过暴力搜索找到合适的密钥来制造想要的解密结果。fcrypt 是56位密钥的 AFS 专用分组密码,运算速度约18M/s,几毫秒到1秒就能找到所需密钥。

攻击目标也更为优雅——直接修改`/etc/passwd`的第一行,把 root 用户的密码字段清空。PAM 遇到空密码时如果配置了`nullok`(常见于桌面环境),直接放行。攻击者执行`su -`,回车,root shell 到手。

这个变体最重要的特点是:不需要用户命名空间。`add_key()`、`socket(AF_RXRPC)`、`splice()`全都不需要特殊权限。这意味着那些通过 AppArmor 等机制封锁了`unshare`调用的系统(例如较新版本的 Ubuntu),xfrm 变体跑不通,但 RxRPC 变体可以。而 RxRPC 模块在大多数发行版中默认不加载,偏偏 Ubuntu 默认加载。两个变体互相覆盖盲区,实现了对几乎所有主流发行版的“通杀”。

影响范围:几乎无系统幸免

两个漏洞的影响范围极为广泛。

Copy Fail 影响了所有从2017年以来(内核4.14及之后)发布的 Linux 内核,直到6.18.22、6.19.12版本才被修复。这意味着 Ubuntu、Debian、RHEL、SUSE、Fedora、Amazon Linux、Arch 等主流发行版全部中招,包括国内常用的麒麟、Deepin 等也在受影响之列。

Dirty Frag 的影响范围几乎同样广泛。xfrm-ESP 漏洞自2017年的提交`cac2661c53f3`起就存在(约9年),RxRPC 漏洞自2023年6月的提交`2dc334f1a63a`起存在。Ubuntu 24.04、RHEL 10.1、openSUSE Tumbleweed、CentOS Stream 10、Fedora 44……全部确认可利用。伯克利安全团队的评价是:“几乎所有 GNU/Linux 发行版和内核版本都受影响,直到得到证实为止”。

更令人担忧的是,Dirty Frag 的公开披露过程并不顺利。Hyunwoo Kim 设置了5天披露期,但5月7日当天就有第三方提前公开了漏洞细节和利用代码,导致各发行版来不及发布正式补丁。截至5月中旬,只有部分上游修复进入主线,各发行版稳定版更新仍在路上。

修复逻辑:放弃性能,保护安全

Copy Fail 的修复方案相对直接:不是修补那4字节的写操作,而是彻底废除“就地处理”这个有问题的优化。修复补丁(`fafe0fa2995a`在内的系列提交)将`algif_aead`恢复为“异地处理”模式,即输入输出使用独立的缓冲区。开发者的总结很坦率:“在algif_aead中就地操作没有任何性能优势,因为源和目标来自不同的映射。移除为就地操作而增加的所有复杂性,直接复制关联数据就行了。”换言之,用一次额外的数据复制换取安全性。

Dirty Frag 的修复更为棘手。xfrm-ESP 漏洞的修复是在`esp_input()`路径中补上缺失的写时复制检查,确保来自外部(包括攻击者通过 splice 传入)的页面不会成为就地解密的目标。上游补丁在公开后24小时内就合入了主线(5月8日),但需要反向移植到各个稳定分支。RxRPC 漏洞的修复进度更慢,截至目前仍在评估中,各发行版正在积极发布正式补丁。

值得注意的是,修复 Copy Fail 对 Dirty Frag 完全无效。两者虽然思路相同,但走的是完全不同的内核代码路径。补救 Copy Fail 时对`algif_aead`的封锁,不会触及 xfrm 或 RxRPC 模块。这就是为什么在2026年5月,系统管理员需要同时应对这两个漏洞。

缓解措施与启示

在正式补丁到来之前,最有效的临时缓解措施是禁用受影响的内核模块:

对于 Copy Fail,禁用`algif_aead`模块。这条措施副作用很小,不影响 dm-crypt、IPsec、OpenSSL 等常见加密需求,只影响显式使用 OpenSSL afalg 引擎的应用。

对于 Dirty Frag,需要禁用`esp4`、`esp6`和`rxrpc`三个模块。但这条措施的副作用较大:会破坏 IPsec VPN 功能和 AFS 分布式文件系统。若系统确实依赖这些服务,需要权衡风险。

这两次漏洞披露给出了几个重要启示:性能优化(零拷贝、就地操作)是漏洞的重灾区,必须审慎对待;“公开日即利用日”的披露模式给防御方带来了巨大压力;而容器环境同样受威胁——攻击者从容器内部可以利用用户命名空间触发漏洞并逃逸至宿主机。

对于 GNU/Linux 系统运维人员而言,这两个漏洞再次印证了同一件事:尽早更新内核是唯一的选择。在补丁可用之前,模块黑名单至少能提供一道防线。及时关注发行版安全公告,将这两组漏洞的修复纳入最高优先级任务,是目前最稳妥的应对策略。

或许有人会借此说自由软件的安全性受到了打击,然而,更多的人会认真思考:其实这是自由软件让系统更安全的的又一次实证——如果 Linux 内核不是自由软件,那么对其的安全性就不会有如此深入的公开研究,而对问题的修复更是不可预期。所以自由软件往往是安全可靠的,而 非自由软件往往是你只有拒绝才能安全的恶意软件

如果你想让自己的系统成为自由软件,那么你可以从容加入 FSF立伯乐 一起让自由软件带你进入自由世界!