
不久前 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。
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"
执行了上述命令之后,攻击文件将无法成功执行:
wgxls@server:/tmp/dirtyfrag$ ./exp
dirtyfrag: failed (rc=1)


