一个零依赖的 Python CLI 工具,用于检查 Linux 主机是否暴露于 CVE-2026-31431("Copy Fail")而无需运行漏洞利用程序。 当受影响的组件可作为内核模块加载时,它还可以应用保守的临时缓解措施。 支持 Debian/Ubuntu、RHEL/Rocky/AlmaLinux、Fedora 和 SUSE。
pip install copyfail-guard
copyfail-guard
CVE-2026-31431 是 algif_aead(AF_ALG AEAD 套接字)内核接口中的一个逻辑缺陷,
它允许非特权本地用户对任何可读文件的页缓存执行受控的 4 字节写入,从而导致 root 权限提升。
CVSS 7.8,自内核 4.14 起存在,已于 2026 年 4 月起在稳定版本中修复。
存在公开的漏洞利用程序,且该漏洞已被列入 CISA KEV。
某些漏洞检查等同于"运行漏洞利用程序并观察是否成功"。 在生产主机上这样做并不合适。 copyfail-guard 采用非漏洞利用的方法。它不会尝试触发该缺陷、 修改 setuid 二进制文件或证明可利用性。相反,它会检查主机状态 (内核版本、模块加载状态、modprobe 配置)并报告该机器是否看起来已暴露。
fix 有意保持最小化——它不会调用你的包管理器。
永久修复需要通过发行版的正常更新机制升级内核。
pip install copyfail-guard
或者无需安装,直接从代码检出目录运行:
PYTHONPATH=src python3 -m copyfail_guard detect
copyfail-guard [--json] [--dry-run] [--quiet] [detect | fix | reset]
$ copyfail-guard
[copyfail-guard] CVE-2026-31431 (Copy Fail) — 易受攻击
发行版: Ubuntu 24.04.1 LTS (debian 系列)
内核: 6.8.0-50-generic (分支 6.12, 修复版本 6.12.85)
模块: algif_aead — 以 .ko 形式加载
缓解措施: 无
建议操作:
1. 立即应用缓解措施:
sudo copyfail-guard fix
2. 更新内核以获得永久修复:
将此系统上的内核更新至 6.12.85 或更高版本(以你的发行版集成
CVE-2026-31431 修复后所发布的版本为准),然后重启。
在应用之前始终使用 --dry-run 进行预览:
$ sudo copyfail-guard --dry-run fix
[copyfail-guard] fix (dry-run) — OK
[ ok ] 预检检查 (Linux, 主机, root)
[skip] 将写入 modprobe 黑名单 [/etc/modprobe.d/cve-2026-31431-copyfail-guard.conf]
[skip] 将尝试卸载 algif_aead (当前未加载) [algif_aead]
[skip] 将追加审计记录 [/var/log/copyfail-guard.log]
$ sudo copyfail-guard fix
[copyfail-guard] fix — OK
[ ok ] 预检检查 (Linux, 主机, root)
[ ok ] 已写入 modprobe 黑名单 [/etc/modprobe.d/cve-2026-31431-copyfail-guard.conf]
[ ok ] 已卸载 algif_aead [algif_aead]
[ ok ] 已追加审计记录 [/var/log/copyfail-guard.log]
永久修复的下一步:
使用发行版的正常更新机制将内核更新至已修补 CVE-2026-31431 的版本,然后重启。
如果模块当前正在使用中,卸载步骤可能会失败。在这种情况下, 持久化的 modprobe 规则仍然可以成功安装,copyfail-guard 会将卸载失败 报告为警告类型的操作记录,而不是假装模块已被移除。
--json 在 stdout 上输出结构化文档,适用于 jq、Ansible 或 SOAR 流水线:
$ copyfail-guard --json | jq .verdict
"vulnerable"
$ copyfail-guard --json | jq '{verdict, kernel: .kernel.patched_threshold}'
{
"verdict": "vulnerable",
"kernel": "6.12.85"
}
在升级到已修补内核后,使用 reset 子命令移除由 fix 安装的
modprobe 规则:
$ sudo copyfail-guard --dry-run reset
[copyfail-guard] reset (dry-run) — OK
[skip] 将移除 /etc/modprobe.d/cve-2026-31431-copyfail-guard.conf
$ sudo copyfail-guard reset
[copyfail-guard] reset — OK
[ ok ] 已移除 /etc/modprobe.d/cve-2026-31431-copyfail-guard.conf
如有需要,重启以允许 algif_aead 再次加载。
reset 是幂等的——如果文件已不存在,则退出码为 0 并显示
"无需操作"消息。然后重启。
容器。 fix 拒绝在容器内运行,因为 /proc/modules 反映的是宿主内核,
但容器无权加载或卸载模块。请在宿主机上直接运行 copyfail-guard。
内置 algif_aead。 某些内核将 algif_aead 直接编译进镜像
(CONFIG_CRYPTO_USER_API_AEAD=y)。在此配置下 modprobe 缓解措施无效;
唯一的修复方式是升级内核。detect 在这种情况下会报告
unmitigable_builtin。运行 fix 仍会安装 modprobe 规则
(可防止任何并存的可加载副本被加载),但内置实例不受影响——
升级内核并重启才是唯一真正的补救措施。
blacklist 与 install … /bin/false。 两种指令都能阻止普通的自动加载,
但 install algif_aead /bin/false 更强,因为它还能阻止普通的显式
modprobe algif_aead 调用。具有足够权限的管理员仍可绕过 modprobe 策略,
例如使用底层模块加载工具或特殊的 modprobe 标志。copyfail-guard 始终安装
更强的形式。如果你的系统已有普通的 blacklist 指令,该工具会报告
mitigated,但会发出建议升级的提示。
SELinux/AppArmor。 在 RHEL 上写入 /etc/modprobe.d/ 通常会从父目录继承
system_u:object_r:modules_conf_t:s0,因此 copyfail-guard 写入的文件通常
不需要手动重新标记。
initramfs。 在主流发行版中,algif_aead 通常不包含在启动镜像中,
因此 copyfail-guard 在安装 modprobe 规则后不会运行 update-initramfs -u 或
dracut -f。如果你的发行版或本地构建将 algif_aead 包含在 initramfs 中,
请遵循你的发行版的内核/模块指南。
Apache 2.0 — 参见 LICENSE。
| 子命令 | 操作 |
|---|
detect | 将五个信号(内核版本、/proc/modules、modules.builtin、modules.dep、modprobe 配置)组合为六种判定之一 |
fix | 原子地写入 install algif_aead /bin/false modprobe 规则,并尝试卸载 algif_aead |
reset | 移除由 fix 安装的 modprobe 规则(在升级到已修补内核后运行) |
| 代码 | 含义 |
|---|
0 | 安全 — 判定为 patched、mitigated 或 not_applicable;或持久化修复步骤成功 |
1 | 易受攻击 — 判定为 vulnerable 或 unmitigable_builtin |
2 | 错误 — 无法确定状态、前置条件被拒绝,或持久化修复步骤失败 |
| 判定 | 描述 |
|---|
patched | 当前运行的内核已达到或超过修复版本 |
mitigated | 内核易受攻击,但 algif_aead 已被 modprobe 配置阻止 |
not_applicable | 内核易受攻击,但此系统上不存在 algif_aead |
vulnerable | 内核易受攻击,模块可加载,且无缓解措施 |
unmitigable_builtin | algif_aead 已编译进内核镜像 — modprobe 缓解措施无效;需要升级内核 |
unknown | 无法解析内核版本,或超出评估范围 |