注意:这篇文章上次更新于102天前,文章内容可能已经过时。
This article was last updated102 days ago, the content may be outdated.


不久前 Copy Fail 刚刚曝光,Linux 又迎来了一个新的重磅安全漏洞:Dirty Frag。
与 Copy Fail 类似,Dirty Frag 也利用了 零拷贝 的特性来篡改普通用户只有读权限的文件,但它作用的 Linux 模块有所不同。
同样地,如果修改 /usr/bin/su,攻击者就能够获取 root 权限。
几乎所有主流 Linux 发行版都受影响,而且该漏洞从 2017 年就已经存在。
更可怕的是,这次漏洞在官方尚未正式修复之前,就已经被第三方公开披露,这意味着 Linux 社区目前还没有可用的补丁来防护该漏洞。
演示
Dirty Frag 的 PoC 可以在 GitHub 上找到:
https://github.com/V4bel/dirtyfrag
我在 Ubuntu 24.04 上测试了这个 PoC,成功获取了 root 权限:

原理
Dirty Frag 属于与 Dirty Pipe 和 Copy Fail 同一类的漏洞。然而,Dirty Pipe 是覆盖 struct pipe_buffer,而 Dirty Frag 则是覆盖 struct sk_buff 的 frag。
在 Copy Fail 中,攻击者使用 splice(file -> pipe -> AF_ALG_fd) 将一个攻击者固定的 page cache 页植入 TX SGL。
在 recv() 内部,TX SGL 的最后 4 个字节(tag)会被分离到 areq->tsgl 并通过 sg_chain 链接到 RX SGL 的末尾。
调用 aead_request_set_crypt(req, src=RX, dst=RX) 决定使用原地模式(in-place mode),而 scatterwalk_map_and_copy(tmp+1, dst, assoclen+cryptlen, 4, 1) 会执行一次 4 字节的 seqno_lo 临时写操作到 dst 的末尾,作为字节重排的一部分。
在正常的 IPsec 路径下,该位置是 skb 的 tag 区,因此写入是无害的。但当攻击者固定的 page 被放置在该位置时,原有假设就被破坏了。Dirty Frag 是一种漏洞,其攻击模式可以在源自 splice 的非线性 skb 的 frag 上复现。
xfrm-ESP Page-Cache 写入:esp_input 绕过 skb_cow_data,直接在 frag 上运行 crypto_authenc_esn_decrypt。
RxRPC Page-Cache 写入:rxkad_verify_packet_1 使用 pcbc(fcrypt) 在 frag 上进行原地单块解密。需要注意的是,Dirty Frag 的触发不依赖于 algif_aead 模块是否可用。换句话说,即使在应用了已知 Copy Fail 缓解措施(如 algif_aead 黑名单)的系统上,你的 Linux 仍然可能受到 Dirty Frag 的攻击。
如何缓解
因为负责任披露(responsible disclosure)的时间表和保密期(embargo)已经被打破,目前任何发行版都不存在补丁。请使用以下命令卸载存在漏洞的模块并清理 page cache。
1 | sh -c "printf 'install esp4 /bin/false\ninstall esp6 /bin/false\ninstall rxrpc /bin/false\n' > /etc/modprobe.d/dirtyfrag.conf; rmmod esp4 esp6 rxrpc 2>/dev/null; echo 3 > /proc/sys/vm/drop_caches; true" |
执行了上述命令之后,攻击文件将无法成功执行:
1 | wgxls@server:/tmp/dirtyfrag$ ./exp |
Not long after Copy Fail was exposed, Linux has welcomed another blockbuster security vulnerability: Dirty Frag.
Similar to Copy Fail, Dirty Frag also exploits the zero-copy feature to tamper with files that ordinary users only have read access to, but it targets a different Linux subsystem.
Likewise, if /usr/bin/su is modified, an attacker can gain root privileges.
Almost all mainstream Linux distributions are affected, and this vulnerability has existed since 2017.
Even scarier, this time the vulnerability was publicly disclosed by a third party before the official fix was ready — meaning the Linux community currently has no available patch to defend against it.
Demo
The Dirty Frag PoC can be found on GitHub:
https://github.com/V4bel/dirtyfrag
I tested this PoC on Ubuntu 24.04 and successfully gained root privileges:

How It Works
Dirty Frag belongs to the same family of vulnerabilities as Dirty Pipe and Copy Fail. However, Dirty Pipe overwrites struct pipe_buffer, while Dirty Frag overwrites the frag of struct sk_buff.
In Copy Fail, the attacker uses splice(file -> pipe -> AF_ALG_fd) to plant an attacker-controlled page cache page into the TX SGL.
Inside recv(), the last 4 bytes (the tag) of the TX SGL are separated into areq->tsgl and chained to the end of the RX SGL via sg_chain.
Calling aead_request_set_crypt(req, src=RX, dst=RX) selects in-place mode, and scatterwalk_map_and_copy(tmp+1, dst, assoclen+cryptlen, 4, 1) performs a 4-byte seqno_lo temporary write to the end of dst as part of the byte rearrangement.
In the normal IPsec path, that location is the skb’s tag area, so the write is harmless. But when an attacker-pinned page is placed at that location, the original assumption is broken.Dirty Frag is a vulnerability whose attack pattern can be reproduced on the frags of non-linear skbs originating from splice.
xfrm-ESP Page-Cache Write: esp_input bypasses skb_cow_data and runs crypto_authenc_esn_decrypt directly on the frag.
RxRPC Page-Cache Write: rxkad_verify_packet_1 uses pcbc(fcrypt) to perform in-place single-block decryption on the frag.Note that triggering Dirty Frag does not depend on whether the algif_aead module is available. In other words, even on systems that have applied known Copy Fail mitigations (such as blacklisting algif_aead), your Linux may still be vulnerable to Dirty Frag.
How to Mitigate
Because the responsible disclosure timeline and embargo have already been broken, no distribution currently has a patch. Please use the following command to unload the vulnerable modules and clear the page cache.
1 | sh -c "printf 'install esp4 /bin/false\ninstall esp6 /bin/false\ninstall rxrpc /bin/false\n' > /etc/modprobe.d/dirtyfrag.conf; rmmod esp4 esp6 rxrpc 2>/dev/null; echo 3 > /proc/sys/vm/drop_caches; true" |
After running the above command, the exploit will fail to execute successfully:
1 | wgxls@server:/tmp/dirtyfrag$ ./exp |


