跳转至

Cloudflare Copy Fail Linux 内核漏洞应急响应

📊 Level ⭐⭐⭐ | 11.5KB

概述

CVE-2026-31431(代号 "Copy Fail")是一个 Linux 内核本地提权漏洞,2026-04-29 公开披露。Cloudflare 安全团队在 48 小时内完成了从检测到全量缓解的闭环,展示了大规模基础设施的安全运维 harness。

漏洞机制

AF_ALG + Page Cache 交互缺陷

漏洞位于 Linux 内核的 AF_ALG 套接字加密 API 与页面缓存(page cache)的交互中:

  • AF_ALG 是内核提供的用户态加密接口,允许通过套接字进行加密操作
  • 内核的 Copy-on-Write (CoW) 机制在处理加密缓冲区时存在越界写(out-of-bounds write)
  • 攻击者可通过精心构造的 copy_file_range 系统调用序列触发内存损坏
  • 最终实现本地权限提升(local privilege escalation)

攻击链

  1. 创建 AF_ALG 套接字并绑定加密算法
  2. 通过 splice/sendmsg 将页面缓存页送入加密操作
  3. 利用 CoW 语义在加密过程中修改共享页面
  4. 触发 out-of-bounds write,覆盖相邻内核内存
  5. 通过控制覆盖内容实现任意代码执行

Cloudflare 应急响应 Harness

时间线(48 小时闭环)

时间 动作
2026-04-29 (上午) CVE 公开,安全团队启动评估
2026-04-29 (下午) 确认受影响内核版本范围
2026-04-30 (上午) eBPF 追踪程序 draft 完成
2026-04-30 (下午) eBPF tracing pipeline 全量部署,实现 AF_ALG socket 使用的完整可见性
2026-05-01 (上午) BPF-LSM 缓解策略验证通过
2026-05-01 (下午) 全量滚动部署缓解措施

三层防御架构

第一层:内核模块移除 - 直接卸载 af_alg 内核模块 - 简单有效但可能影响依赖 AF_ALG 的合法应用

第二层:eBPF 可见性追踪 - 使用 eBPF tracing 监控所有 AF_ALG socket 操作 - 提供完整的利用尝试可见性 - 不阻断操作,仅记录和告警

第三层:BPF-LSM 主动缓解 - 使用 BPF-LSM (Linux Security Module) 在内核层面阻止漏洞利用路径 - 不需要修改内核代码或重启系统 - 可精细控制:仅阻止恶意模式,不影响合法加密操作 - overnight draft → morning validation → afternoon rollout

Harness 工程亮点

  1. eBPF 作为安全运维基础设施 — 不仅用于网络监控,还用于内核漏洞的检测和缓解
  2. BPF-LSM 实时策略部署 — 无需内核升级即可部署安全策略,比传统 patch-then-reboot 流程快得多
  3. 48 小时从披露到全量缓解 — 展示了成熟的安全 incident response harness
  4. 三层防御冗余 — 模块移除 + eBPF 追踪 + BPF-LSM 缓解,任何一层失效都有备份

对 Harness Engineering 的启示

这个案例展示了安全运维中的 harness engineering 原则:

  • 可观测性优先:eBPF tracing 提供了内核级的实时可见性,是快速响应的基础
  • 策略热部署:BPF-LSM 允许在不重启的情况下部署安全策略,类似于 agent harness 的热更新能力
  • 渐进式缓解:三层防御逐层部署,每层独立验证,符合 harness 的渐进式治理理念
  • 自动化优先:从 eBPF 程序 draft 到全量部署的流程高度自动化

相关主题

深度分析

一个 4 字节越界写如何穿透信任边界

根因不是加密算法,而是性能优化留下的语义债:为支持 in-place 加解密,algif_aead 把源页与目标页链进同一条 scatterlist,却不强制算法尊重写边界,authencesn 校验 AEAD 时越界多写 4 字节。放大器是 splice()——它能把任意可读文件的 page cache 页作为引用页送进同一条链,写入目标因此从内核临时缓冲区变成全局页缓存,攻击者同时掌握"改哪个文件、哪个偏移、写哪 4 字节"三个自由度,足以定点改写 setuid 二进制的 .text。更隐蔽的是返回值与副作用解耦:recvmsg() 返回 -EBADMSG(操作"失败"),4 字节却已落进跨进程共享的页缓存,被污染的 setuid 二进制在页换出前对所有用户生效,execve("/usr/bin/su") 即以 root 执行注入代码。上游修复选择整体回退这次 in-place 优化,等于承认该抽象承载不了"算法可能越界"的假设。

为什么「本地提权」在 CDN 语境下是舰队级问题

LPE 常被矮化为单机风险,但多租户边缘网络的影响半径由信任边界密度而非 CVSS 决定:单节点同时服务租户流量、承载隔离负载、运行控制面进程,一次 LPE 就是从"共享硬件"跨到同机高权限凭据的桥,容器隔离只是纵深一层而非终点;数十万台机器又把单节点极小的成功率放大成可观的舰队期望,而利用代码的传播快于补丁波次;更棘手的是信任反转——被污染的恰是发行版自带 setuid 二进制,最被信任的组件成了载荷载体,绕开基于文件哈希的白名单防御。所以 CDN 的资产不是某台机器,而是整片机群行为的一致性:目标不是堵住一个洞,而是在补丁覆盖每台机器之前,让舰队整体走不到那条代码路径。

48 小时闭环的前提:可见性先于阻断

时间线里最值得学的不是缓解工具,而是顺序。

  • 检测必须行为级:团队不等本 CVE 的签名或规则,用既有行为检测平台做内部验证即于数分钟内告警,并把整条执行链(脚本解释器 → 内核加密子系统 → 提权二进制)关联为单一事件。对 0-day 而言写签名追不上披露,能提前存在的只有行为基线。
  • 可见性闸门先于执行闸门:上生产前先用 eBPF 挂 socket() 统计全舰队 AF_ALG 真实使用者,把"会不会打断业务"从猜测变成测量;证实仅一个内部服务是合法用户后,阻断策略才放行。同一份遥测又充当依赖清单的校验器——文档与代码搜索会漏报,metric 层不会。

这两步合成的不是"更快",而是"更敢":拦截动作的可信度已被数据证明,团队才敢在数小时内对全舰队下判断。

内核补丁的物流学:livepatch、重启窗口与版本偏斜

瓶颈不是"能不能修",而是"多久让所有机器跑上修好的内核"。这里叠加三重互不同步的时间常数:上游向主 LTS 的 backport 尚未落地(mainline 修复已存在约一个月)、内部自动构建与暂存验证的周期、边缘四周一次的重启节拍——全都不由安全团队控制。

于是双轨并行:BPF-LSM 在 socket_bind 上按二进制白名单放行 AF_ALG,零重启全量生效;补丁内核走正常波次并收敛,形成"每台机器要么跑补丁内核、要么被策略拦住"的兜底覆盖。波次启动后,先前已过重启窗口的机器必须手工补重启——这就是版本偏斜无法消除的原因:舰队任意时刻都是多版本混合态,"是否已修复"只能按机粒度查询,不能按发布批次推断。更硬的教训是最初的缓解尝试(卸载 algif_aead)在暂存暴露依赖冲突并被回滚,生产未受影响;回滚可用正因它在暂存被真正演练过,但也因此回滚从来不是方案——它只把系统还原到"已知可被利用"的状态,买回时间而非安全。

Harness 化与 agent 的介入边界

这次响应之所以快,是因为它几乎不是被临时发明的,而是沿既有管道执行:信号 → 分诊 → 缓解 → 验证 → 回归。信号层是行为检测覆盖加 eBPF 给出的 AF_ALG 使用者画像,分诊层是内核版本映射与 48 小时回溯威胁狩猎,缓解层是 BPF-LSM 草拟、验证、分阶段放行,验证层在已知易受攻击的节点确认利用失效,回归层把内核依赖清单审计、未用模块裁剪与 playbook 增强沉淀回来。决定成败的是闸门设计:观测闸门与执行闸门分离,把一个不可逆的舰队级动作拆成两个各自可验证的小步;验证手段单行可复现(已缓解机器上绑定 AF_ALG 应得 Operation not permitted),使"真的修好了"成为可脚本化的事实而非信心。

放到 agent 视角,可自动化与不可让渡的边界由动作是否可回滚划定,而非能力高低:跨源日志的时间窗回溯关联、内核版本与服务依赖清单对账、补丁波次排程与版本偏斜可视化、验证脚本生成都可交给 agent;而向生产内核或安全策略推送变更、解除缓解闸门、宣判威胁狩猎"干净"、在信息不全时承担剩余风险必须由人拍板——只读分析最坏只是浪费一次查询,一次误推的阻断策略却是全舰队故障。这也解释了可撤销的运行时策略(BPF-LSM、eBPF 观测)为何优于内核替换:不只在速度,更在于它把不可回滚的动作(重启、换内核)推迟到人类看过数据之后。参见 Cilium Tetragon 这类 eBPF 运行时安全实践,以及 Corvus AI 内核漏洞 Agent 代表的"agent 参与内核漏洞处置"方向——后者的价值上限正由这条边界界定。

实践启示

  1. 把"能否检测"前置到任何漏洞之前:为关键攻击链建立行为级基线(进程链 + 内核子系统 + 提权二进制关联),而非依赖逐 CVE 签名。
  2. 阻断式变更必须先过观测闸门:先用只读遥测确认谁在真正使用待关闭的能力,再放行执行闸门,把"会不会打断业务"从猜测变成数据。
  3. 给内核 API 依赖建可测量的清单:文档、代码搜索与负责人记忆都会漏报;按二进制维度统计 syscall/socket family 使用,下一次应急才能在几分钟内界定影响面。
  4. 运行时缓解与内核补丁双轨并行,并显式定义收敛条件:给出"要么跑补丁内核、要么被策略拦住"这类可验证终态,避免覆盖空洞与版本偏斜盲区。
  5. 回滚是测量工具,不是补救方案:先在暂存演练新缓解(依赖冲突正是在那里暴露),但永远假设回滚不可用——回滚后的系统恰处于已知可被利用的状态。
  6. 按动作可回滚性划分 agent 自动化与人类审批:日志狩猎、波次规划、验证脚本可高度自动化;推策略、换内核、解除闸门等生产写路径保留人工签核,并把不可逆动作尽量后置。

关联