Linux 内核 "Copy Fail" 本地提权漏洞(CVE-2026-31431)

漏洞概述

  • 漏洞名称:Copy Fail
  • 编号:CVE-2026-31431
  • 评级:High / Important(CVSS 7.8),社区公认为极高危本地提权漏洞(可通过简单 PoC 实现 root)
  • 影响范围:影响 2017 年以来(引入 commit 72548b093ee3 后)几乎所有主流 Linux 发行版的内核
  • 发现时间:2026 年 3 月下旬(由 Xint 等研究员发现)
  • 修复补丁合并时间:2026-04-01 前后(主要修复 commit a664bf3d603dc3bdcf9ae47cc21e0daec706d7a5 已合并入 Linux 内核 mainline)
  • PoC 公开时间:2026-04-30

漏洞本质:Linux 内核 crypto 子系统(algif_aead 模块)中对 in-place 操作的处理逻辑错误,结合 AF_ALG 接口 + splice(),允许非特权用户对任意可读文件的 page cache 进行受控 4 字节写入,从而修改 setuid 二进制(如 /usr/bin/su)实现本地权限提升。

漏洞风险说明

只要系统存在普通用户(包括 nginxwww-data 等无法登录的系统账户),且攻击者能以该用户身份执行任意代码(Web 漏洞、容器逃逸、恶意脚本等),即可利用此漏洞提权至 root。

该漏洞对容器宿主机、共享服务器、开发测试环境威胁极大,也可用于容器逃逸。

临时缓解措施

由于绝大多数应用(如 Nginx、OpenSSH、MySQL 等)使用用户态加密库(OpenSSL 等),不依赖内核 AF_ALG,因此可以安全禁用相关模块。

# 立即卸载模块(如果已加载)
rmmod algif_aead 2>/dev/null || true

# 防止模块被重新加载
echo "install algif_aead /bin/false" > /etc/modprobe.d/disable-algif.conf

命令作用说明

  1. rmmod algif_aead 2>/dev/null || true
    立即尝试移除当前已加载的 algif_aead 模块。
  2. echo "install algif_aead /bin/false" > /etc/modprobe.d/disable-algif.conf
    使用 install 指令:当系统尝试加载该模块时,执行 /bin/false(失败),从而阻止加载。

验证方法

# 1. 检查模块是否仍加载(无输出表示缓解基本生效)
lsmod | grep algif_aead

# 2. 检查配置文件
cat /etc/modprobe.d/disable-algif.conf

# 3. 测试是否还能加载模块(缓解成功应失败)
modprobe algif_aead && echo "缓解失败,模块仍可加载" || echo "缓解成功,模块已被阻止加载"

影响评估

对系统的影响
对于绝大多数服务器场景,移除 algif_aead 模块基本无负面影响
algif_aead 是内核提供给用户态的可选加密接口,大部分常见服务均不依赖它。

需要注意的少数情况
只有极少数定制应用明确通过 AF_ALG 套接字调用内核 AEAD 硬件加速时,禁用后相关功能会失效。此类情况在生产环境中非常罕见。

适用性说明

  • CentOS 7
    状态:不受影响(Not affected)
    Red Hat 官方声明:Vulnerable Code not Present。
    CentOS 7 / RHEL 7 内核基于 3.10.x,未引入导致漏洞的 commit,因此无需执行临时缓解措施(执行也无害,但无必要)。
  • AlmaLinux 8(及 RHEL 8 / Rocky Linux 8 / CentOS 8 Stream 等 EL8 系列)
    状态:受影响(Affected)
    Red Hat 将其标记为 Important(部分为 Fix deferred)。建议立即执行临时缓解,并尽快升级 kernel。
  • Debian 11 (Bullseye)
    状态:受影响。内核 5.10 系列受影响,建议同样执行临时缓解并关注 Debian Security Update。

生效的原理与发行版无关,这两条命令在所有基于 modprobe 机制的 Linux 发行版上是通用的,只跟内核是否把 algif_aead 编译成模块有关。

在部分发行版/内核中(尤其是较新的 AlmaLinux 8/9),algif_aead 可能是 built-in(直接编译进内核,不可 rmmod)。此时 rmmod 无效,install /bin/false 也无法阻止(因为模块不会被动态加载)。

如何确认 algif_aead 是否被编译进内核(built-in)的实用方法

按推荐顺序排列(从最简单到最彻底)。

1. 最快速推荐命令

# 1. 检查内核配置选项
zgrep CONFIG_CRYPTO_USER_API_AEAD /proc/config.gz 2>/dev/null || \
grep CONFIG_CRYPTO_USER_API_AEAD /boot/config-$(uname -r) 2>/dev/null || \
grep CONFIG_CRYPTO_USER_API_AEAD /lib/modules/$(uname -r)/config 2>/dev/null

# 2. 如果上面没有输出,再检查 modules.builtin
grep -E "algif_aead|crypto/algif_aead" /lib/modules/$(uname -r)/modules.builtin

结果判断

  • 输出中看到 =ybuilt-in(编译进内核)rmmodinstall ... /bin/false 都无法阻止。
  • 输出中看到 =m作为可加载模块,你的临时缓解命令有效。
  • 没有任何输出 → 可能未启用该功能(不受影响或配置被禁用)。

2. 其他常用检查方法

# 检查模块是否可被 modprobe
modinfo algif_aead

→ filename: (builtin)
这明确确认 algif_aead 是 built-in(内置在内核中),不是可加载模块。

filename:       /lib/modules/5.10.0-16-amd64/kernel/crypto/algif_aead.ko
vermagic:       5.10.0-16-amd64 SMP mod_unload modversions 

filename 以 .ko 结尾 → 这是可加载模块
vermagic 中包含 mod_unload → 支持卸载

**Debian 11**:
grep CONFIG_CRYPTO_USER_API_AEAD /boot/config-$(uname -r)

3. 如果确认是 built-in,该怎么办?

algif_aead 是 built-in 时,rmmodinstall /bin/false 都无效。此时推荐以下更彻底的缓解方式:

# 方案一:推荐的完整临时缓解(阻止后续任何尝试加载/使用这些模块的操作)
cat > /etc/modprobe.d/disable-af_alg.conf << 'EOF'
# Mitigate CVE-2026-31431 "Copy Fail" - Disable AF_ALG and related interfaces
blacklist af_alg
blacklist algif_aead
blacklist algif_hash
blacklist algif_skcipher
blacklist algif_rng

install af_alg /bin/false
install algif_aead /bin/false
install algif_hash /bin/false
install algif_skcipher /bin/false
install algif_rng /bin/false
EOF

# 立即尝试移除
rmmod af_alg algif_aead algif_hash algif_skcipher algif_rng 2>/dev/null || true

# 重新生成 initramfs,将新的禁用配置打包进去(AlmaLinux 8 必须执行)
dracut -f

执行后验证:
python3 -c '
import socket
try:
    s = socket.socket(socket.AF_ALG, socket.SOCK_SEQPACKET, 0)
    s.bind(("aead", "authencesn(hmac(sha256),cbc(aes))"))
    print("【警告】AF_ALG 仍然可用,缓解不彻底")
    s.close()
except Exception as e:
    print("【成功】AF_ALG 已被阻止")
'

这个 Python 一行命令正是从 CVE-2026-31431(Copy Fail) 的官方 PoC 和技术分析中提炼出来的核心前置步骤:
- 它尝试创建一个 AF_ALG socket 并绑定到 authencesn(hmac(sha256),cbc(aes)) 这个具体的 AEAD 算法模板。
- 这正是漏洞利用链的第一步(Socket setup + bind)。
- 如果这一步能成功执行,就说明攻击者可以进入漏洞的核心路径(algif_aead 相关功能可用)。
- 如果失败(抛出异常),则说明 AF_ALG / algif_aead 相关功能已被有效阻断。

更强缓解措施
内核启动参数禁用初始化函数
grubby --update-kernel=ALL --args="initcall_blacklist=algif_aead_init"

# 查看是否添加成功
grubby --info=ALL | grep initcall_blacklist

reboot
再次验证

保持当前配置
不要删除 /etc/modprobe.d/disable-af_alg.conf
保留 initcall_blacklist=algif_aead_init 参数


# 方案二:等待官方 kernel 更新(最佳长期方案)
dnf update kernel kernel-core kernel-modules --refresh

一旦 AlmaLinux / Red Hat 发布包含 CVE-2026-31431 修复的 kernel 更新(当前仍是 Fix deferred),建议立即升级。

升级 kernel 后的清理工作
当官方修复内核发布并升级后,建议做以下清理:
# 移除内核参数
grubby --update-kernel=ALL --remove-args="initcall_blacklist=algif_aead_init"

# 可选:移除 modprobe 禁用文件(如果不再需要)
# rm -f /etc/modprobe.d/disable-af_alg.conf