FlawOpen

flawopen.com/Teardowns/cve-2026-31431-linux-algif-aead-copy-fail

● CVE-2026-31431 · CVSS 7.8 · 高危
安全研究 · FlawOpen

CVE-2026-31431:Linux 内核 Copy Fail 漏洞

Copy Fail 是 Linux AF_ALG AEAD 路径中的本地提权漏洞。原地优化混淆了源和目标映射;上游修复恢复非原地处理,CISA 已将该 CVE 列入 KEV。[1], [2], [5]

💡 通俗易懂的原理解析 (ELI5)

图书管理员要在复印件上做标记,但机器的快捷方式让铅笔落在原书上。加密路径的原地快捷处理使结果写入可能到达另一映射页面。内核修复分别处理源和目标,确保写入只落在指定的副本页面。[3], [8]

核心概念与专有名词

AF_ALG
Linux 为用户进程提供的加密套接字接口。[8], [3]
AEAD
带关联数据的认证加密:加密数据并认证额外的未加密元数据。[8]
algif_aead
AF_ALG 对 AEAD 算法的实现,包括存在源/目标处理缺陷的路径。[3]
Page cache
内核中的文件内容缓存;对映射页面的写入可能影响磁盘回写前的读取。[8]
CWE-1288 / CWE-669
NVD 将 CWE-1288 列为来自 redhat-SADP 的映射;Red Hat 页面也列出该 CWE。加拿大网络安全中心的警报将此问题归类为 CWE-669。这些是不同来源给出的分类,不能互换。[11], [7], [5], [9], [10]

框架映射

根本原因剖析 (Root Cause)

2017 年变更 72548b093ee3 在 algif_aead 中引入原地优化。源和目标可能来自不同映射。authencesn 处理可能把临时数据写出预期输出区域;原地 scatterlist 可能使写入落到通过 splice() 提供的文件页缓存页面。Linux CVE 通知将修复描述为恢复非原地处理,同时保留关联数据复制。需要本地访问且易受影响路径已启用。CVSS 7.8(AV:L/AC:L/PR:L/UI:N/S:U/C:H/I:H/A:H);不是未经身份验证的远程入口。[1], [3], [8], [7], [9], [10]

攻击执行流程分解

步骤 1

本地进程进入加密 API

具有本地访问权限的进程通过 AF_ALG 请求 AEAD 操作,随后由 algif_aead 处理。单独的远程请求无法到达此接口。[8], [7]

步骤 2

数据路径使用原地优化

受影响实现将源和目标视为可安全共享页面,但此操作中的映射实际不同。[8], [3]

步骤 3

写入越过预期输出边界

authencesn 处理期间,临时数据可能写出输出区域并到达经 splice() 提供的文件页缓存页面。[8]

步骤 4

内核重新分离源和目标

修复移除不必要的原地处理复杂性,直接复制关联数据并恢复非原地处理。[1], [3]

源代码对比:漏洞与安全实现

这是概念性总结,并非内核源码原文或可编译补丁。上游通知称修复基本回退 72548b093ee3,但保留关联数据复制,因为源和目标映射不同。[3], [2]

源码摘录: crypto/algif_aead.c (_aead_recvmsg)

存在漏洞的实现
/* 修复前:让加密操作在原缓冲区中就地执行。 */
rsgl_src = areq->first_rsgl.sgl.sg;

if (ctx->enc) {
    memcpy_sglist(areq->first_rsgl.sgl.sg, tsgl_src, processed);
    af_alg_pull_tsgl(sk, processed, NULL, 0);
} else {
    memcpy_sglist(areq->first_rsgl.sgl.sg, tsgl_src, outlen);
    /* 为认证标签构建并串联 TX scatterlist。 */
    areq->tsgl_entries = af_alg_count_tsgl(sk, processed, processed - as);
    /* ... */
}

aead_request_set_crypt(&areq->cra_u.aead_req, rsgl_src,
                       areq->first_rsgl.sgl.sg, used, ctx->iv);
加固后的安全修复
/* 修复后:为每个请求保留单独的源 scatterlist。 */
processed = used + ctx->aead_assoclen;
areq->tsgl_entries = af_alg_count_tsgl(sk, processed);
/* 分配并初始化 areq->tsgl,然后将 TX 页面加入其中。 */
af_alg_pull_tsgl(sk, processed, areq->tsgl);
tsgl_src = areq->tsgl;

/* 复制关联数据,同时保持源和目标分离。 */
rsgl_src = areq->first_rsgl.sgl.sg;
memcpy_sglist(rsgl_src, tsgl_src, ctx->aead_assoclen);
aead_request_set_crypt(&areq->cra_u.aead_req, tsgl_src,
                       areq->first_rsgl.sgl.sg, used, ctx->iv);

工程与系统安全加固清单

参考来源