缓解Docker引擎中的CVE-2026-31431(“Copy Fail”)漏洞

概述

CVE-2026-31431(“Copy Fail”)是一个于2026年4月披露的Linux内核权限提升漏洞,影响AF_ALG加密子系统中的algif_aead模块。该漏洞允许拥有AF_ALG套接字访问权限的非特权用户控制性地写入页面缓存(page cache)。由于页面缓存是所有文件读取操作的基础,攻击者可以临时修改主机上任意可读文件的内容,这可能导致本地权限提升(例如通过篡改setuid二进制文件)或影响同一主机上的其他容器和进程。对于运行在未打补丁的内核上的Docker容器,这是一个严重的安全风险。Docker Engine团队通过在运行时层面实施多层缓解措施,为尚未获得内核补丁的用户提供即时保护。

核心概念

  • AF_ALG 套接字:Linux内核提供的一种允许用户空间程序访问内核加密算法的套接字家族。这是此漏洞利用的系统调用接口。
  • 页面缓存 (Page Cache):内核用于缓存文件数据的内存区域。它是一个全局资源,所有进程(包括主机和所有容器)对同一文件的读取都会共享此缓存。这是漏洞能够跨越容器边界产生影响的关键原因。
  • seccomp (Secure Computing Mode):一种Linux内核安全特性,允许进程限制自身可以使用的系统调用。Docker使用自定义seccomp配置文件来限制容器内的系统调用。
  • LSM (Linux Security Modules):如AppArmor和SELinux,它们为内核提供了强制访问控制(MAC)框架,可以挂载到内核的socket创建回调函数,从而在更深层次上控制资源访问,而不仅仅是系统调用层面。
  • socketcall(2):一个在x86_64架构上存在的旧式多路复用系统调用,它将socket、bind、connect等多个操作封装在一个系统调用中。其参数通过指针传递,使得seccomp过滤器无法检查具体的地址族,是此次缓解措施中遇到的关键技术挑战。

实践

针对CVE-2026-31431的缓解措施经历了两个主要迭代,最终在Docker Engine v29.4.3中形成了一套有效的多层防御方案。

第一次尝试:仅使用seccomp(v29.4.2)

Docker Engine v29.4.2首先更新了默认的seccomp配置文件,通过在socket(2)系统调用的参数中过滤AF_ALG地址族来阻止创建相关套接字。然而,团队很快发现仅阻塞socket(2)是不够的。

  • 问题:攻击者可以通过socketcall(2)系统调用来创建套接字,绕过基于参数的过滤器。因为socketcall将参数打包到用户空间数组中,seccomp的BPF过滤器无法解析其中的具体地址族。
  • 解决方案:团队在seccomp规则中彻底禁用了socketcall(2)系统调用。
  • 意外后果:此禁令过于宽泛,导致许多依赖32位兼容模式(通过socketcall)的旧版二进制程序(如基于i386架构的glibc、Go运行时的GOARCH=386、SteamCMD、Wine等)网络功能完全失效。这是一个严重的回归问题。

最终方案:基于LSM的防御(v29.4.3)

认识到seccomp在系统调用边界上存在的局限性,Docker Engine v29.4.3转向利用Linux安全模块(LSM)的内核钩子,实现了更精确的控制。

  1. 回滚socketcall禁令:恢复了32位兼容性。
  2. 增强AppArmor配置文件:在默认的AppArmor配置文件中添加了 deny network alg, 规则。由于AppArmor钩入内核的security_socket_create()回调,无论通过socket(2)还是socketcall(2)创建套接字,该规则都能有效阻止AF_ALG套接字。此方案适用于启用AppArmor的系统(如Ubuntu、Debian)。
  3. 集成SELinux策略:为使用SELinux的系统(如Fedora、RHEL、CentOS)提供了一个CIL策略模块,可以拒绝container_domain类型创建alg_socket。这需要Docker守护进程以--selinux-enabled模式运行。
  4. 保留seccomp作为纵深防御:继续在默认seccomp配置文件中阻止socket(AF_ALG),作为针对socket(2)系统调用路径的纵深防御。

如果无法立即升级Docker引擎或内核,可采取临时缓解措施:

  • 禁用内核模块:在/etc/modprobe.d/目录下配置文件中添加 blacklist af_alg 和 blacklist algif_aead。此方法仅在相关模块以可加载模块形式(CONFIG_CRYPTO_USER_API=m)编译时有效。
  • 使用自定义seccomp配置文件:应用一个明确拒绝AF_ALG的自定义seccomp配置文件。

SRE要点

与可靠性和安全性的关联

此案例深刻体现了安全漏洞对系统可靠性的直接影响。一个内核漏洞可能通过容器逃逸或横向移动,影响整个节点及其上运行的所有工作负载的可用性和完整性。快速、有效的运行时缓解是缩短漏洞暴露窗口、保护服务级别的关键手段。

最佳实践与常见反模式

  • 纵深防御:Docker的最终方案结合了seccomp(系统调用层)和AppArmor/SELinux(内核对象层),展示了有效的安全纵深。单一安全层可能存在盲区(如socketcall),多层协同才能覆盖更广的攻击面。
  • 警惕缓解措施的副作用:第一次尝试(v29.4.2)的教训表明,安全加固必须充分考虑兼容性和业务影响。SRE在部署安全补丁时,需要在生产环境进行严格测试,避免造成服务中断。
  • 保持更新:无论是内核还是容器运行时,及时更新是防御已知漏洞的最可靠方式。Docker Engine的更新可以比内核补丁更快地部署到所有主机,成为重要的应急响应工具。

相关指标(SLI/SLO/SLA)

虽然此事件不直接产生传统的性能SLI,但可以关联到以下安全与运维SLO:

  • 漏洞平均缓解时间 (MTTM):从CVE公开到部署有效缓解措施的时间。Docker团队的快速响应为SRE团队赢得了时间。
  • 关键安全补丁部署覆盖率:衡量在指定时间内(例如,在漏洞披露后72小时内),已对受影响主机应用缓解措施(如升级引擎或内核)的比例。
  • 安全相关事件发生率:通过监控和日志,跟踪因利用此漏洞尝试而触发的安全事件,其发生率的降低可作为缓解措施有效的间接指标。