CVE-2026-31431 漏洞修复说明
背景
CVE-2026-31431(又称 Copy Fail)是 Linux 内核 crypto 子系统中的一个高危本地提权漏洞,问题位于
algif_aead 模块,即内核 userspace crypto API 的 AEAD socket 接口(AF_ALG)。该漏洞可通过 AF_ALG + splice() 影响内核 page cache,攻击者在已能于节点上执行用户态代码的前提下,可能进一步提权至节点 root,或产生跨容器影响(同一宿主机上的进程共享内核 page cache)。Linux kernel 社区对该漏洞的修复描述为:crypto: algif_aead - Revert to operating out-of-place。具体信息详见【安全通告】Linux Kernel 本地权限提升漏洞风险通告(CVE-2026-31431)。影响范围
受影响版本:
Linux 内核:包含
CONFIG_CRYPTO_USER_API_AEAD=m 或 =y 编译配置、且尚未应用 CVE-2026-31431 修复补丁的版本。TKE 节点:运行上述受影响内核版本的普通节点、原生节点、超级节点。
注册节点:操作系统由用户自行控制,需用户自行评估内核版本及风险。
说明:
若内核编译时
CONFIG_CRYPTO_USER_API_AEAD=n(未编译该模块),则天然免疫,无需操作。攻击条件:
攻击者需已能够在目标节点的容器或用户态进程中执行代码(如通过容器逃逸、exec 权限、恶意镜像等方式获得节点执行能力),方可尝试利用此漏洞进行本地提权。该漏洞不可远程直接利用,但在多租户集群、CI/CD Runner 集群、开放 exec/debug 权限的集群中风险更高。
以下集群需要重点关注:
集群类型 | 风险说明 |
多租户集群 | 不可信用户可提交 Pod,风险高 |
CI/CD Runner 集群 | 构建任务通常执行不可信代码,风险高 |
在线业务混部集群 | 单业务容器被攻破后可能影响整节点 |
开放 exec / debug 权限的集群 | 攻击者更容易获得容器内代码执行能力 |
运行高权限 Pod 的集群 | 漏洞利用后横向风险更大 |
GPU / MaaS 推理集群 | 通常承载第三方模型、代码、插件或用户任务,需要重点评估 |
修复建议
一、彻底修复(推荐)
不同节点类型的根治方案不同:
新建节点默认使用修复版本,天然不受此漏洞影响。
存量节点可通过置换节点完成根治:先对节点执行驱逐(drain)将业务 Pod 迁移至其他节点,再将旧节点移出集群,最后新建节点加入集群(新节点默认使用修复版本镜像)。
原生节点的操作系统由 TKE 统一管控。请关注 TKE 后续公告更新,在 TKE 发布包含修复补丁的节点镜像后:
新建节点默认使用修复版本,天然不受此漏洞影响。
存量节点可通过置换节点完成根治:先对节点执行驱逐(drain)将业务 Pod 迁移至其他节点,再将旧节点移出集群,最后新建节点加入集群(新节点默认使用修复版本镜像)。
超级节点的底层节点资源由 TKE 统一管控。请关注 TKE 后续公告更新,在 TKE 发布修复后:
新建 Pod 默认运行在修复版本的节点上,天然不受此漏洞影响。
存量 Pod 可通过重建 Pod(删除后由控制器重新调度)使其重建完成根治。
二、临时缓解(内核升级前)
临时缓解不能替代内核升级,请尽快完成彻底修复。
在完成节点 OS 升级前,可采用临时缓解措施降低攻击面。普通节点 / 原生节点 / 超级节点默认不加载
algif_aead,整体风险较低。临时缓解通过 DaemonSet 写入 /etc/modprobe.d 黑名单并卸载模块。该 DaemonSet 须使用高权限(hostPID/hostNetwork/privileged),属于节点级高危变更,必须先 canary 后全量。Step 1:选择 1~3 台低风险节点预检并打标:
单节点预检命令:可以先在少量节点上执行。
uname -rlsmod | grep '^algif_aead' || echo "algif_aead not loaded"modinfo algif_aead 2>/dev/null || echo "algif_aead module not found or built-in"test -f /etc/modprobe.d/blacklist-algif_aead.conf && \\cat /etc/modprobe.d/blacklist-algif_aead.conf || \\echo "blacklist config not found"
检查结果 | 结论 |
lsmod 能看到 algif_aead | 当前运行态存在风险,需要卸载 |
配置文件不存在 | 重启后仍可能被自动加载,需要修复 |
只有 blacklist algif_aead | 建议增强为 install algif_aead /bin/false |
modinfo 查不到,但功能仍存在 | 可能是 built-in 或路径差异,需要进一步确认 |
模块正在被使用,无法卸载 | 需结合业务评估,可能要通过节点重启生效 |
预检完成后,对节点打上标签:
kubectl label node <node-1> algif-aead-fix=canarykubectl label node <node-2> algif-aead-fix=canary
Step 2:保存为
disable-algif-aead-canary.yaml 并部署 Canary DaemonSet:apiVersion: apps/v1kind: DaemonSetmetadata:name: disable-algif-aeadnamespace: kube-systemlabels:app: disable-algif-aeadspec:selector:matchLabels:app: disable-algif-aeadupdateStrategy:type: RollingUpdaterollingUpdate:maxUnavailable: 1template:metadata:labels:app: disable-algif-aeadspec:hostPID: truehostNetwork: truetolerations:- operator: ExistsnodeSelector:algif-aead-fix: canaryrestartPolicy: Alwayscontainers:- name: disable-algif-aeadimage: busybox:1.36imagePullPolicy: IfNotPresentsecurityContext:privileged: truevolumeMounts:- name: host-rootmountPath: /hostreadOnly: falsecommand:- /bin/sh- -c- |set -euMODULE="algif_aead"CONF="/host/etc/modprobe.d/blacklist-algif_aead.conf"STATE_DIR="/host/var/lib/cve-2026-3143"STATE_FILE="${STATE_DIR}/pre-fix-state.json"ROLLBACK_DONE="${STATE_DIR}/rollback-done"echo "[INFO] node=$(hostname) start precheck"mkdir -p /host/etc/modprobe.dmkdir -p "${STATE_DIR}"# ========== 清理上一次回滚标记(支持反复 disable/rollback) ==========if [ -f "${ROLLBACK_DONE}" ]; thenecho "[FIX] clearing previous rollback marker"rm -f "${ROLLBACK_DONE}"fi# ========== 记录禁用前状态(用于回滚) ==========MODULE_LOADED="false"MODULE_LINE=""if grep -q "^${MODULE} " /proc/modules; thenMODULE_LOADED="true"MODULE_LINE=$(grep "^${MODULE} " /proc/modules)fiCONF_EXISTED="false"CONF_BACKUP=""if [ -f "${CONF}" ]; thenCONF_EXISTED="true"CONF_BACKUP=$(cat "${CONF}" 2>/dev/null || echo "")fi# 仅首次执行时写入状态文件,避免重复运行覆盖原始状态if [ ! -f "${STATE_FILE}" ]; thencat > "${STATE_FILE}" <<SNAP{"timestamp": "$(date -u '+%Y-%m-%dT%H:%M:%SZ')","hostname": "$(hostname)","kernel": "$(uname -r)","module_was_loaded": ${MODULE_LOADED},"module_proc_line": "${MODULE_LINE}","blacklist_conf_existed": ${CONF_EXISTED},"blacklist_conf_backup": "${CONF_BACKUP}","cve": "CVE-2026-3143"}SNAPchmod 0644 "${STATE_FILE}"echo "[STATE] pre-fix state saved to ${STATE_FILE}"elseecho "[STATE] state file already exists, skip (idempotent)"fiecho "[STATE] recorded state:"cat "${STATE_FILE}"# ========== Precheck ==========if [ "${MODULE_LOADED}" = "true" ]; thenecho "[PRECHECK] ${MODULE} is loaded: ${MODULE_LINE}"elseecho "[PRECHECK] ${MODULE} is not loaded"fiif [ "${CONF_EXISTED}" = "true" ]; thenecho "[PRECHECK] existing config:"echo "${CONF_BACKUP}"elseecho "[PRECHECK] config not found"fi# ========== Fix ==========echo "[FIX] writing blacklist config"cat > "${CONF}" <<EOF# Managed by TKE DaemonSet disable-algif-aead# CVE: CVE-2026-3143blacklist algif_aeadinstall algif_aead /bin/falseEOFchmod 0644 "${CONF}"syncecho "[FIX] try to unload ${MODULE}"if grep -q "^${MODULE} " /proc/modules; thenif chroot /host /sbin/modprobe -r "${MODULE}" 2>/tmp/modprobe-r.err; thenecho "[FIX] modprobe -r ${MODULE} succeeded"elseecho "[WARN] modprobe -r failed:"cat /tmp/modprobe-r.err || trueif chroot /host /sbin/rmmod "${MODULE}" 2>/tmp/rmmod.err; thenecho "[FIX] rmmod ${MODULE} succeeded"elseecho "[ERROR] failed to unload ${MODULE}:"cat /tmp/rmmod.err || truefifielseecho "[FIX] ${MODULE} is not loaded, skip unload"fi# ========== Postcheck ==========echo "[POSTCHECK] config:"cat "${CONF}"if grep -q "^${MODULE} " /proc/modules; thenecho "[POSTCHECK][FAIL] ${MODULE} is still loaded"elseecho "[POSTCHECK][OK] ${MODULE} is not loaded"fiwhile true; dosleep 3600donevolumes:- name: host-roothostPath:path: /type: Directory
kubectl apply -f disable-algif-aead-canary.yaml# 观察(成功标准:日志出现 [POSTCHECK][OK] algif_aead is not loaded)kubectl -n kube-system get pod -l app=disable-algif-aead -o widekubectl -n kube-system logs -l app=disable-algif-aead --tail=50
Step 3:Canary 通过后,删除 YAML 中的
nodeSelector 段,全量 apply:kubectl apply -f disable-algif-aead.yamlkubectl -n kube-system rollout status ds/disable-algif-aead --timeout=10mkubectl -n kube-system get ds disable-algif-aead
修复后检查
# DaemonSet 状态(期望 DESIRED = READY)kubectl -n kube-system get ds disable-algif-aead# 日志检查(成功标准: [POSTCHECK][OK] algif_aead is not loaded)kubectl -n kube-system logs -l app=disable-algif-aead --tail=300 | grep -E "POSTCHECK|ERROR|WARN|FAIL|OK"# 抽样检查宿主机配置POD=$(kubectl -n kube-system get pod -l app=disable-algif-aead -o jsonpath='{.items[0].metadata.name}')kubectl -n kube-system exec "$POD" -- cat /host/etc/modprobe.d/blacklist-algif_aead.confkubectl -n kube-system exec "$POD" -- grep '^algif_aead ' /proc/modules || echo "not loaded - OK"# 节点与业务状态kubectl get nodeskubectl get events -A --sort-by='.lastTimestamp' | tail -100
重点确认没有新增:
NodeNotReady / MemoryPressure / DiskPressure / PIDPressure / NetworkUnavailable / FailedCreatePodSandBox / FailedMount,以及业务层面的 Pod 重启、错误率、CNI/DNS 连通性、存储挂载、GPU 调度(含 NVIDIA device plugin)是否正常;若有自研加密组件、IPsec 或依赖内核 crypto API 的场景,需额外确认。
异常处理与回滚
若模块卸载失败(
rmmod: ERROR: Module algif_aead is in use),不要强制破坏业务进程,确认配置文件已写入后记录该节点为"已配置未卸载",业务低峰重启或替换节点。若日志出现 [POSTCHECK][FAIL] algif_aead is still loaded,说明配置已落盘但运行态卸载失败,常见原因包括:模块正在被使用、模块为 built-in、节点缺少 modprobe/rmmod、安全策略阻止卸载。若 DaemonSet Pod 无法启动,常见原因为 PSP / OPA / Gatekeeper 策略阻止特权容器,需临时为 kube-system 命名空间放开
k8sPSPPrivilegedContainer、k8sPSPHostNamespace、k8sPSPHostNetworkingPorts 限制,修复完成后恢复。若节点出现异常,先诊断,如节点承载关键业务则立即驱逐后回滚或替换节点:
kubectl describe node <node-name>kubectl get events -A --sort-by='.lastTimestamp' | tail -200# 关键业务节点:先驱逐kubectl cordon <node-name>kubectl drain <node-name> --ignore-daemonsets --delete-emptydir-data
若业务出现异常(加密、网络、安全组件等),立即停止扩大范围,执行:
kubectl -n kube-system delete ds disable-algif-aead
然后执行下方回滚 DaemonSet 恢复配置。回滚动作包括:删除宿主机黑名单配置、可选重新加载
algif_aead、检查业务恢复情况。注意删除 DaemonSet 只会删除 Pod,不会自动删除宿主机上的配置文件,需通过以下回滚 DaemonSet 清理。保存为
rollback-algif-aead.yaml 并执行:apiVersion: apps/v1kind: DaemonSetmetadata:name: rollback-algif-aeadnamespace: kube-systemlabels:app: rollback-algif-aeadspec:selector:matchLabels:app: rollback-algif-aeadupdateStrategy:type: RollingUpdaterollingUpdate:maxUnavailable: 1template:metadata:labels:app: rollback-algif-aeadspec:hostPID: truehostNetwork: truetolerations:- operator: ExistsrestartPolicy: Alwayscontainers:- name: rollback-algif-aeadimage: busybox:1.36imagePullPolicy: IfNotPresentsecurityContext:privileged: truevolumeMounts:- name: host-rootmountPath: /hostreadOnly: falsecommand:- /bin/sh- -c- |set -euMODULE="algif_aead"CONF="/host/etc/modprobe.d/blacklist-algif_aead.conf"echo "[ROLLBACK] node=$(hostname) start rollback"if [ -f "${CONF}" ]; thenecho "[ROLLBACK] remove ${CONF}"rm -f "${CONF}"syncelseecho "[ROLLBACK] config not found, skip"fiecho "[ROLLBACK] try to reload ${MODULE}, optional"if grep -q "^${MODULE} " /proc/modules; thenecho "[ROLLBACK] ${MODULE} already loaded"elseif chroot /host /sbin/modprobe "${MODULE}" 2>/tmp/modprobe.err; thenecho "[ROLLBACK] modprobe ${MODULE} succeeded"elseecho "[WARN] modprobe ${MODULE} failed; module may be unavailable or not required"cat /tmp/modprobe.err || truefifiif [ -f "${CONF}" ]; thenecho "[POSTCHECK][FAIL] config still exists"elseecho "[POSTCHECK][OK] config removed"fiif grep -q "^${MODULE} " /proc/modules; thenecho "[POSTCHECK] ${MODULE} is loaded"elseecho "[POSTCHECK] ${MODULE} is not loaded"fiwhile true; dosleep 3600donevolumes:- name: host-roothostPath:path: /type: Directory
kubectl apply -f rollback-algif-aead.yaml# 观察kubectl -n kube-system get pod -l app=rollback-algif-aead -o widekubectl -n kube-system logs -l app=rollback-algif-aead --tail=200# 成功后清理kubectl -n kube-system delete ds rollback-algif-aead
常见问题
TKE 普通 / 原生 / 超级节点默认有风险吗?
默认情况下,这三种节点的操作系统由 TKE 管控,均不会开启
algif_aead 模块,整体风险较低。注册节点需用户自行评估。禁用 algif_aead 是否会影响 HTTPS、SSH、普通 TLS?
通常不会。普通 TLS/SSH/OpenSSL 使用用户态 crypto 库,不依赖
algif_aead。如有自研内核加密组件或 IPsec 场景,需先灰度验证。DaemonSet 临时修复后是否还需要升级内核?
需要。DaemonSet 仅是临时缓解,根治需升级到含 CVE-2026-31431 修复补丁的内核或节点镜像。
为什么要写 install algif_aead /bin/false,而不是只写 blacklist?
blacklist 主要阻止自动加载,install algif_aead /bin/false 进一步阻止手动 modprobe,两者同时配置安全加固效果更强。DaemonSet 为什么需要 privileged 权限?
需要修改宿主机
/etc/modprobe.d 并执行内核模块卸载,没有 privileged 和宿主机根目录挂载无法完成操作。集群开了 PSP 怎么办?
若开启了
k8sPSPPrivilegedContainer、k8sPSPHostNamespace、k8sPSPHostNetworkingPorts 且未豁免 kube-system,需先临时放开 kube-system 命名空间,修复完成后恢复。超级节点方案不受此限制影响。如果修复后有业务异常怎么办?