Linux内核“Copy Fail”漏洞深度解析:从零拷贝优化到稳定提权的技术全貌

近日,Linux社区披露了一枚高危本地提权漏洞——CVE-2026-31431,并赋予其富有讽刺意味的代号Copy Fail。该漏洞潜伏在内核加密子系统(Crypto API)长达数年之久,攻击者只需一个普通用户权限,即可在无竞争条件、无需反复重试的条件下,稳定地将权限提升至root,且篡改操作可常驻内存、不留磁盘痕迹。本文将从技术原理、触发路径、利用手法到修复方案,进行一次严谨而深入的复盘。


1. 漏洞概览

项目 内容
漏洞名称 Linux Kernel 本地权限提升漏洞(Copy Fail)
CVE 编号 CVE-2026-31431
漏洞类型 内核本地权限提升(越界写入)
危害等级 高风险
影响内核版本 commit 72548b093ee3 ≤ 版本 < commit a664bf3d603d
已知受影响发行版 Ubuntu 24.04 LTS、RHEL 8/9/10、Amazon Linux 2023、SUSE 16 等
公开情况 漏洞细节及PoC已公开,存在被大规模利用的风险

2. 背景知识:AF_ALG 与零拷贝解密路径

要理解Copy Fail的成因,必须先了解Linux Crypto API提供的用户态加密接口 AF_ALG

2.1 AF_ALG 套接字体系

AF_ALG是内核向用户态暴露加密/解密能力的通用框架,应用程序通过创建 socket(AF_ALG, SOCK_SEQPACKET, 0) 并绑定具体算法(如 aead),即可利用内核驱动完成高性能加解密操作,无需在用户态和内核态之间拷贝数据。

对于AEAD(认证加密)算法,关键结构 algif_aead 负责两个核心路径:

  • 加密:接收用户明文,产出密文+认证标签。
  • 解密:接收密文和认证标签,验证完整性后输出明文。

解密操作主要通过 recvmsg() 系统调用触发,用户可提供一块目标缓冲区来接收解密后的数据。

2.2 splice 带来的“零拷贝”优化

出于性能考量,内核在2017年合并了提交 72548b093ee3,为AEAD解密路径引入了splice零拷贝优化。简单来说,当用户通过 splice() 将数据从一个文件描述符传输到AF_ALG套接字时,内核并非将数据拷贝到临时缓冲区,而是直接把目标文件的页缓存页面链接到内核内部的 scatterlist(散列表)结构中,作为解密结果的接收区。这一优化消除了CPU复制开销,但为后续的越界写入埋下伏笔。

2.3 authencesn 算法与IPsec ESN支持

受影响的内核AEAD算法 authencesn 是为IPsec扩展序列号(ESN)而设计的认证加密模板。其硬件/软件实现中,解密过程不仅需要验证完整性,还会对接收缓冲区中特定偏移处的序列号字节进行重排序,具体做法是:将解码后的4字节序列号临时写入接收缓冲区的偏移 assoclen + cryptlen 处(即关联数据长度+密文长度之后),后续再进行处理。正常情况下,该位置位于AF_ALG分配的合法缓冲区尾部,并没有越界问题。


3. 漏洞根因:当零拷贝遇上“临时写入”

Copy Fail 的本质是上述两种机制的不兼容组合,最终触发了边界外的受控4字节写入

3.1 漏洞触发的精确场景

  1. 攻击者打开了一个AF_ALG套接字,并绑定到 authencesn 算法,准备进行解密操作。
  2. 攻击者使用 splice() 系统调用,将一个已打开的目标文件(例如 /usr/bin/su)的页缓存页面“拼”进AF_ALG套接字的接收缓冲区。内核零拷贝路径将这些页面直接链入 recvmsg() 将使用的输出散列表(scatterlist)。
  3. 攻击者通过 recvmsg() 触发解密。authencesn 模块在执行解密时,计算偏移 assoclen + cryptlen,并将4字节重排后的序列号写入该处。然而,由于接收缓冲区采用了零拷贝的页缓存碎片,其实际内存布局是连续的若干页,且 assoclen + cryptlen 的末尾可能恰好位于某一页的边界,接下来的4字节会毫无保护地跨越缓冲区边界,写入紧邻其后的另一页缓存——正是先前 splice 链接进来的目标文件内容。
  4. 这4字节的内容完全可由攻击者控制(来自解密输入中精心构造的认证数据与序列号)。写入目标文件的页缓存后,内核认为该页仍然是“干净”的,不会触发回写(因为没有调用 set_page_dirty),篡改可常驻内存,直到页面被回收或文件被重新读取。

3.2 图示说明

3.3 为什么如此稳定且“无竞争”?

传统的内存损坏漏洞常依赖竞态窗口或堆喷,而Copy Fail的优雅之处在于:

  • 布局确定性:利用 splice 直接操控页缓存链入散列表的顺序,可精确控制目标文件页在内存中与被溢写缓冲区的相对位置。
  • 触发原子性:一次 recvmsg 调用即可完成越界写入,无需反复尝试。
  • 隐蔽持久化:脏页不写回磁盘,文件系统检查无法发现;但后续对该文件的 readmmap 会直接读取已被篡改的页缓存,从而实现“内存中的rootkit”。

4. 从越界写入到 root 权限——利用思路

攻击者的目标通常是将修改注入到具有 setuid 位的关键系统程序(如 /usr/bin/susudo 等),通过篡改其执行逻辑实现提权。

一种可行的利用方案如下:

  1. 打开目标 setuid 程序(只读即可),获取其文件描述符。
  2. 通过 splice 将程序的一个或多个页缓存页面送入 AF_ALG 套接字,确保这些页面紧跟在解密缓冲区之后。
  3. 构造解密请求,使 authencesn 的临时写入刚好跨越到目标程序的代码段或关键数据结构(如 GOT 表、程序逻辑分支变量等)。写入的4字节可以是:
    • 直接植入一段 shellcode 的跳转指令。
    • 修改条件判断,使程序无条件执行 setuid(0)execve("/bin/sh")
    • 覆盖认证校验值,绕过密码检查。
  4. 调用 recvmsg() 触发解密,程序页缓存被污染。
  5. 执行被篡改的程序。内核会直接从已污染的页缓存中加载“伪装”过的二进制数据,程序按照攻击者意图运行,从而获得 root shell。

由于不需要触碰磁盘,系统完整性校验(如 IMA、只读文件系统等)无法拦截。即使在功击完成后退出进程,该页缓存污染仍可能维持,为后续持久化访问留下后门。


5. 影响范围与自检

受影响内核版本:提交 72548b093ee3 引入零拷贝优化,直到提交 a664bf3d603d 完成修复。具体影响范围包括所有启用了 CONFIG_CRYPTO_USER_API_AEAD=y 的内核。使用以下命令可确认模块是否加载:

lsmod | grep algif_aead

如果输出非空,则系统存在暴露风险。

主流发行版状况(截至漏洞披露时刻):

  • Ubuntu 24.04 LTS:受影响,安全更新待发布。
  • Red Hat Enterprise Linux 8/9/10:受影响。
  • Amazon Linux 2023:受影响。
  • SUSE Linux Enterprise 16:受影响。

建议及时关注各发行版安全公告(如 Ubuntu CVE-2026-31431 页面、Red Hat 安全公告)。


6. 修复与缓解方案

6.1 升级内核至安全版本

官方补丁 commit a664bf3d603d 修复了该问题。补丁的核心思路是禁用 AEAD 解密路径中 splice 的零拷贝页缓存引用,将这部分页面改为复制后再送入散列表,从而杜绝越界写入可能。所有用户应尽快将内核升级到包含该提交的版本。

补丁地址
https://git.kernel.org/stable/c/a664bf3d603dc3bdcf9ae47cc21e0daec706d7a5

6.2 临时缓解措施:禁用 algif_aead 模块

若业务环境无法立即重启升级,可强制禁止加载 algif_aead 模块:

echo "install algif_aead /bin/false" > /etc/modprobe.d/disable-algif-aead.conf

重启即生效,或手动执行 modprobe -r algif_aead(如果当前未被占用)。注意这将使依赖 AF_ALG AEAD 的应用程序(如某些IPsec实现)降级或失效,需评估业务影响。

6.3 临时加固:限制 splice 使用

理论上可限制非特权用户调用 splice 的能力,但此措施对大量正常服务影响较大,仅建议在无法禁用模块时作为极端过渡手段。


7. 总结与思考

Copy Fail 漏洞是一次经典的内核“组合拳”漏洞:看似无害的零拷贝性能优化,遇上 authencesn 算法对缓冲区尾部的越界假设,最终酿成严重后果。它再次警示我们:

  • 零拷贝技术是一柄双刃剑,将不同域的页直接链入内解析路径时,必须严格审计其内存边界。
  • 密码接口的安全边界不能仅仅依赖于算法本身的安全性,还必须考虑数据传递过程中的内存管理。
  • 及时响应与升级是关键。该漏洞 PoC 已公开,利用门槛极低,相关团队应立即行动。

随着云原生和容器技术的普及,内核漏洞的影响面日益扩大。深入理解这类漏洞的利用链条,不仅能帮助我们更好地应急,更能为系统编程与安全设计提供宝贵的教训。


参考文献

  • NVD: CVE-2026-31431
  • Linux Kernel git: commit a664bf3d603d
  • theori-io/copy-fail-CVE-2026-31431 PoC 仓库
  • Ubuntu / Red Hat 官方安全公告

(全文共计约 2100 字)

Logo

AtomGit 是由开放原子开源基金会联合 CSDN 等生态伙伴共同推出的新一代开源与人工智能协作平台。平台坚持“开放、中立、公益”的理念,把代码托管、模型共享、数据集托管、智能体开发体验和算力服务整合在一起,为开发者提供从开发、训练到部署的一站式体验。

更多推荐