摘要

CVE-2026-31431,又名 Copy Fail,是 Linux Kernel 中一个影响较广的本地权限提升漏洞。该漏洞位于 algif_aead 用户态加密接口相关逻辑中,攻击者在具备普通本地用户权限的情况下,可能通过 AF_ALGsplice() 与 AEAD 加密路径的组合,实现对 page cache 的受控写入,最终影响 setuid-root 程序执行流程并获得 root 权限。

该漏洞对多用户 Linux 主机、容器节点、CI/CD Runner、在线代码执行平台、Notebook 平台和沙箱环境影响较大。本文将从漏洞背景、影响范围、技术原理、非破坏性 PoC、复现思路、检测方法、修复方案和临时规避方式几个方面进行分析。

本文仅用于安全研究、漏洞验证和防御加固。请勿在未授权环境中测试或利用漏洞。
在这里插入图片描述

一、漏洞基本信息

项目 内容
CVE 编号 CVE-2026-31431
漏洞名称 Copy Fail
漏洞类型 Linux Kernel 本地权限提升
影响组件 algif_aead / AF_ALG / Kernel Crypto API
攻击权限 本地普通用户
攻击复杂度
影响结果 普通用户可能提升为 root
CVSS 7.8
修复方式 升级内核或禁用相关攻击面

公开参考:

  • https://copy.fail/
  • https://nvd.nist.gov/vuln/detail/CVE-2026-31431
  • https://cert.europa.eu/publications/security-advisories/2026-005/
  • https://www.sysdig.com/blog/cve-2026-31431-copy-fail-linux-kernel-flaw-lets-local-users-gain-root-in-seconds

二、漏洞背景

Linux 内核提供了 Kernel Crypto API,用于向内核和用户态程序提供加密能力。其中,AF_ALG 是 Linux 暴露给用户态的加密 socket 接口。

用户态程序可以通过类似下面的方式调用内核加密能力:

socket(AF_ALG, SOCK_SEQPACKET, 0)

algif_aead 则是 AF_ALG 中用于 AEAD 算法的接口。AEAD 全称为 Authenticated Encryption with Associated Data,即“带关联数据的认证加密”。

正常情况下,普通用户调用这些接口并不应该获得修改系统敏感内存或提权的能力。但 CVE-2026-31431 的问题在于,特定数据路径组合会导致来自 page cache 的页面被错误地当作可写目标缓冲区使用。

三、影响范围

该漏洞影响包含相关 algif_aead in-place 优化逻辑、但尚未合入修复补丁的 Linux 内核版本。

高风险环境包括:

  1. 多用户 Linux 服务器
    普通用户账号可能被提升为 root。

  2. Kubernetes / Docker 容器节点
    容器内低权限代码可能借助内核漏洞影响宿主机。

  3. CI/CD Runner
    如果 Runner 会执行不可信 PR、构建脚本或测试代码,风险较高。

  4. 在线代码运行平台
    例如在线评测、沙箱执行、Notebook、实验平台等。

  5. 已经存在 WebShell 或 RCE 的服务器
    攻击者可将该漏洞作为后续本地提权手段。

需要注意的是,判断是否受影响不能只看 uname -r。不同发行版可能会将安全补丁 backport 到旧版本号内核中,因此应以发行版安全公告和实际补丁状态为准。

四、漏洞原理分析

4.1 涉及的关键机制

该漏洞涉及三个核心机制:

1. AF_ALG

AF_ALG 是 Linux 内核提供的加密算法 socket 接口。用户态程序可以通过它调用内核中的加密算法。

2. algif_aead

algif_aeadAF_ALG 中处理 AEAD 加密算法的接口。漏洞主要出现在该模块相关的数据处理路径中。

3. splice()

splice() 是 Linux 的零拷贝系统调用,可在文件描述符之间移动数据,例如文件、管道、socket 等。

零拷贝机制可以提高性能,但也使得数据页的所有权和读写语义变得更加复杂。

4.2 根因简述

该漏洞与 algif_aead 中的 in-place 优化有关。

所谓 in-place 操作,是指源缓冲区和目标缓冲区复用同一块内存区域,从而减少额外拷贝,提高性能。

问题在于,当攻击者将 AF_ALG、AEAD 加密操作和 splice() 组合使用时,来自 page cache 的页面可能进入本应可写的目标 scatterlist。最终,低权限用户可能借助加密接口触发对 page cache 的受控写入。

研究方披露的关键能力是:

攻击者可以对任意可读文件对应的 page cache 进行小范围受控写入。

这意味着攻击者不一定需要直接写磁盘文件,也能影响该文件在内存中的内容。

五、为什么可以导致提权?

Linux 系统中存在一些 setuid-root 程序,例如:

/usr/bin/su
/usr/bin/passwd
/usr/bin/sudo

这类程序的特点是:普通用户执行时,程序可以在特定条件下以 root 权限运行。

如果攻击者能够污染这些 setuid-root 程序在 page cache 中的内容,就可能影响程序执行流程。由于修改发生在 page cache 中,而不是磁盘文件本身,所以会出现几个特点:

  1. 磁盘文件内容未必发生变化。
  2. 文件哈希检测可能发现不了异常。
  3. 重启或 page cache 回收后,污染通常会消失。
  4. 被污染的 setuid 程序一旦执行,可能触发 root 权限代码路径。

这也是 Copy Fail 漏洞比较危险的地方:它攻击的是内核缓存层,而不是传统文件写入路径。

六、非破坏性 PoC:检测 AF_ALG AEAD 暴露面

下面的 PoC 不会提权,不会修改系统文件,也不会污染 page cache。它只用于检测当前系统中普通用户是否可以访问 AF_ALG AEAD 相关接口。

保存为:

copyfail_exposure_check.py

代码如下:

#!/usr/bin/env python3
import os
import platform
import socket
import subprocess
import sys

AF_ALG = getattr(socket, "AF_ALG", 38)

AEAD_CANDIDATES = [
    "authencesn(hmac(sha1),cbc(aes))",
    "authenc(hmac(sha1),cbc(aes))",
]

def run(cmd):
    try:
        return subprocess.check_output(
            cmd,
            text=True,
            stderr=subprocess.DEVNULL
        ).strip()
    except Exception:
        return ""

def has_proc_crypto(name):
    try:
        with open("/proc/crypto", "r", encoding="utf-8", errors="ignore") as f:
            return name in f.read()
    except Exception:
        return False

def try_afalg_aead(alg_name):
    try:
        s = socket.socket(AF_ALG, socket.SOCK_SEQPACKET, 0)
        s.bind(("aead", alg_name))
        s.close()
        return True, None
    except OSError as e:
        return False, f"{e.errno}: {e.strerror}"
    except Exception as e:
        return False, str(e)

def main():
    print("[*] Kernel:", platform.release())
    print("[*] User:", f"uid={os.getuid()} euid={os.geteuid()}")

    config = run([
        "sh",
        "-c",
        "zgrep -h CONFIG_CRYPTO_USER_API_AEAD /proc/config.gz /boot/config-$(uname -r) 2>/dev/null | tail -1"
    ])

    print("[*] CONFIG_CRYPTO_USER_API_AEAD:", config or "unknown")

    loaded = bool(run([
        "sh",
        "-c",
        "lsmod | awk '{print $1}' | grep -x algif_aead"
    ]))

    print("[*] algif_aead loaded:", loaded)
    print("[*] /proc/crypto contains authencesn:", has_proc_crypto("authencesn"))

    exposed = False

    for alg in AEAD_CANDIDATES:
        ok, err = try_afalg_aead(alg)
        if ok:
            print(f"[+] AF_ALG AEAD bind succeeded: {alg}")
            exposed = True
        else:
            print(f"[-] AF_ALG AEAD bind failed: {alg} ({err})")

    print()

    if exposed:
        print("[!] Result: AF_ALG AEAD is reachable by this user.")
        print("[!] If the kernel is unpatched, this host should be treated as potentially vulnerable.")
        sys.exit(2)
    else:
        print("[+] Result: AF_ALG AEAD was not reachable with tested algorithms.")
        print("[+] This may indicate mitigation, missing module, policy block, or unsupported algorithm.")
        sys.exit(0)

if __name__ == "__main__":
    main()

运行方式:

python3 copyfail_exposure_check.py

如果输出中出现:

AF_ALG AEAD bind succeeded

说明当前普通用户可以访问相关攻击面。此时应进一步确认内核是否已经合入修复补丁。

七、漏洞复现建议

不建议直接在生产环境复现真实提权过程。

推荐的复现环境:

  1. 创建隔离虚拟机。
  2. 安装可能受影响的 Linux 内核。
  3. 创建普通用户。
  4. 给虚拟机打快照。
  5. 运行本文提供的非破坏性检测 PoC。
  6. 如需进一步验证真实漏洞利用,应只在授权实验环境中使用研究方公开 PoC。
  7. 测试完成后回滚快照或销毁虚拟机。

基础信息收集命令:

id
uname -a
uname -r
lsmod | grep algif_aead
cat /proc/crypto | grep -A5 -E 'authencesn|aead'

研究方公开页面提供的 exploit 哈希如下,可用于验证样本完整性:

sha256: a567d09b15f6e4440e70c9f2aa8edec8ed59f53301952df05c719aa3911687f9

公开仓库地址:

https://github.com/theori-io/copy-fail-CVE-2026-31431

再次强调:真实 exploit 只应在隔离、授权、可回滚环境中运行。

八、检测方法

8.1 检查内核版本

uname -a
uname -r

但不要只依赖版本号。发行版可能已经 backport 修复补丁。

8.2 检查内核配置

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

如果结果为:

CONFIG_CRYPTO_USER_API_AEAD=y

或:

CONFIG_CRYPTO_USER_API_AEAD=m

说明 AEAD 用户态接口可能存在。

8.3 检查模块状态

lsmod | grep algif_aead
modinfo algif_aead 2>/dev/null

8.4 检查发行版安全状态

Ubuntu / Debian:

apt update
apt list --upgradable | grep -E 'linux-image|linux-generic|linux'

RHEL / Rocky / Alma / Fedora:

dnf updateinfo list --cves | grep CVE-2026-31431
dnf updateinfo info --cve CVE-2026-31431

SUSE:

zypper lp --cve=CVE-2026-31431

九、修复方案

9.1 升级内核

最推荐的修复方式是升级到发行版官方发布的修复版本。

Ubuntu / Debian:

sudo apt update
sudo apt full-upgrade

RHEL / Rocky / Alma / Fedora:

sudo dnf update kernel

SUSE:

sudo zypper patch

升级完成后需要重启系统:

sudo reboot

重启后确认当前内核:

uname -r

十、临时规避方式

如果短时间内无法升级内核,可以先禁用 algif_aead 模块。

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

验证是否卸载:

lsmod | grep algif_aead || echo "algif_aead not loaded"

该方式通常不会影响常见的 OpenSSL、SSH、LUKS、dm-crypt 等场景,但可能影响显式依赖 AF_ALG AEAD 的应用。因此建议在生产环境执行前先评估业务影响。

十一、容器环境加固建议

对于 Kubernetes、Docker、CI Runner 等运行不可信代码的环境,可以通过 seccomp 阻断 AF_ALG socket 创建。

AF_ALG 地址族编号通常为 38

Docker seccomp 规则片段示例:

{
  "names": ["socket"],
  "action": "SCMP_ACT_ERRNO",
  "args": [
    {
      "index": 0,
      "value": 38,
      "op": "SCMP_CMP_EQ"
    }
  ]
}

该策略尤其适合:

  • 自托管 GitLab Runner / GitHub Actions Runner
  • 在线编译平台
  • CTF / OJ 平台
  • Notebook 平台
  • 多租户容器平台

十二、入侵排查建议

可以重点关注以下行为:

  1. 普通用户创建 AF_ALG socket。
  2. 异常调用 splice()
  3. 普通用户频繁执行 setuid-root 程序。
  4. 容器内出现异常 root shell。
  5. /usr/bin/su/usr/bin/passwd/usr/bin/sudo 等程序执行链异常。

需要注意的是,由于该漏洞主要影响 page cache,磁盘文件哈希不一定发生变化。因此,仅依赖文件完整性检测可能不足以发现利用痕迹。

建议结合:

  • auditd
  • eBPF
  • Falco
  • EDR
  • 容器运行时安全策略

进行综合检测。

十三、总结

CVE-2026-31431 是一个典型的 Linux 内核本地提权漏洞。它的危险点在于攻击者不需要直接修改磁盘文件,而是通过内核数据路径污染 page cache,从而影响 setuid-root 程序执行。

对于企业环境,建议按以下优先级处置:

  1. 优先排查多用户主机、容器节点、CI/CD Runner。
  2. 尽快升级内核并重启。
  3. 无法立即升级时,临时禁用 algif_aead
  4. 对容器和不可信代码执行环境限制 AF_ALG
  5. 使用非破坏性 PoC 验证攻击面是否仍然存在。
  6. 结合审计日志和运行时安全工具排查异常行为。

一句话总结:

Copy Fail 不是远程漏洞,但它可以把一个普通本地账号变成 root。在容器、CI 和多租户场景中,应按高优先级漏洞处理。

Logo

有“AI”的1024 = 2048,欢迎大家加入2048 AI社区

更多推荐