TECH

CVE-2026-31431,一个从 2017 年就潜伏在 Linux 内核加密子系统里的提权漏洞。

上周 Linux 社区爆出一个提权漏洞,编号 CVE-2026-31431,绰号 Copy Fail。CVSS 评分 7.8,影响范围从 2017 年起的几乎所有主流发行版——Ubuntu、RHEL、SUSE、Amazon Linux 全中招。

更让人印象深刻的是 PoC 的体量:一段 732 字节的 Python 脚本,不需要改写,直接在上述任意发行版和架构上跑通,拿到 root。

漏洞在哪

问题出在内核加密子系统的 algif_aead 接口,也就是 AF_ALG socket 的 AEAD(关联数据认证加密)部分。

AF_ALG 允许非特权用户通过 socket 调用内核的加密算法,本意是让应用层不用自己实现加密逻辑。splice() 系统调用可以把文件的 页缓存(page cache)页面直接传入这个 socket,省去一次内存拷贝。

问题在于 authencesn 这个加密模板。它在做 AEAD 解密时,会把传入的页缓存页面链成一个可写的 scatterlist,然后往里写临时数据——而且写的范围超出了预期边界。最终结果是:攻击者可以对任意可读文件的页缓存写入 4 个字节,精确控制偏移量。

这 4 个字节足够了。

关键细节:被篡改的页从不会被标记为脏页,所以磁盘上的文件内容和校验和完全不变,只有内存里的缓存版本被动过。传统的文件完整性检测对此无效。

利用路径

攻击链很直接:

  1. 用非特权用户打开一个绑定到 authencesn(hmac(sha256),cbc(aes)) 的 AF_ALG socket
  2. splice() 把目标文件(比如 /usr/bin/su)送进 socket
  3. 构造 AEAD 参数,让算法的临时写操作落在目标偏移
  4. 执行被篡改的 setuid 二进制——以 root 运行

整个过程不需要网络,不需要特殊权限,不需要针对发行版定制。在容器里同样有效,且可以突破容器边界。

影响范围

受影响的内核版本跨度相当大:

  • 4.14 ~ 5.10.253
  • 5.11 ~ 6.12.84
  • 6.13 ~ 7.0-rc6

基本覆盖了 2017 年至今所有未打补丁的内核。CISA 已将其列入已知被利用漏洞目录,要求联邦机构在 2026 年 5 月 15 日前完成修复。

修复方法

打补丁是根本解法。 各发行版已陆续推送内核更新,优先升级。

如果短期内无法重启,临时缓解方案是禁用 algif_aead 模块:

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

重启后生效。这会阻止 algif_aead 加载,代价是依赖内核 AEAD 接口的应用可能受影响,但多数场景下没有实际影响。

一点感想

这个漏洞潜伏了将近十年。AF_ALG 接口本身是有意让非特权用户访问的,splice() 的零拷贝设计也是性能优化的合理选择——但两者组合在一起,加上 authencesn 里那段「不必要复杂」的原地操作逻辑,就出了问题。

补丁的修复思路很干净:把 AEAD 操作从原地(in-place)改回非原地(out-of-place)。源缓冲区和目标缓冲区本来就来自不同的内存映射,原地优化根本没有必要,只是徒增了出错空间。


参考资料:Microsoft Security Blog · Xint 技术分析 · NVD CVE-2026-31431