pedit COW:一场在页面缓存里悄无声息的 root 政变

真正的剑客不在杯中寻毒,而在茶里看见破绽。内核亦然。
零、一句话概括
CVE-2026-46331(绰号 “pedit COW”)是 Linux 内核流量控制子系统中的一个越界写入漏洞。攻击者利用 act_pedit 模块在 Copy-on-Write 阶段的校验缺陷,对共享页面缓存进行越界写入,在不触碰磁盘文件的情况下毒化 /bin/su 的内存映射,最终以非特权用户身份获取 root 权限。
CVSS 评分:7.8(HIGH)|攻击复杂度:低|利用条件:本地、非特权用户在启用了非特权用户命名空间的系统上
漏洞曝出不到 24 小时,公开 PoC 即现身 GitHub。这是一场从 mailing list 上被低估的「例行数据损坏补丁」到 weaponized exploit 的经典演变。
一、先复盘:CoW 这一类漏洞的血脉传承
如果你对 Linux 内核的 page-cache 漏洞稍有涉猎,应该已经对这个家族不陌生了:
| 漏洞名称 | CVE | 年份 | 核心手法 |
|---|---|---|---|
| Dirty Pipe | CVE-2022-0847 | 2022 | splice() 未重置 pipe buffer flags,向已释放的 page cache 写入 |
| Copy Fail | CVE-2024-XXXX | 2024 | copy_file_range() 的 CoW 断裂 |
| DirtyClone | CVE-2026-XXXX | 2026 | io_uring 零拷贝路径越过 page 所有权检查 |
| Dirty Frag | CVE-2026-XXXX | 2026 | 碎片整理过程中 page 引用计数竞争 |
| pedit COW | CVE-2026-46331 | 2026 | act_pedit 运行时偏移解析绕过越界检查 |
它们的本质是同一个「脉门」:
内核在某条快速路径上对页面做了写操作,但这个页面并不归它独占。
这不是内存破坏(memory corruption),这是逻辑漏洞。不涉及 ROP、不涉及 KASLR 绕过、不涉及堆喷。只需要知道哪一页被共享,然后把 payload 写进去——文件完整性校验会告诉你一切正常,而你早已是 root。
二、漏洞机制:一封被投毒的信,信封完好无损
2.1 act_pedit 的正常工作流
tc(traffic control)是 Linux 的流量整形瑞士军刀。其中 pedit action 可以在数据包经过时,实时修改包头字段——比如改 TTL、改 DSCP、改 IP 地址。
当你配置一条 pedit 规则并触发它时,内核调用链大致是:
tcf_pedit_act() → pedit_skb_hdr_offset() // 计算偏移 → tcf_pedit_act() 内部 // 校验写入范围 → 如果页面是共享的(refcount > 1) → 创建私有副本 (CoW) → 写入数据理想情况下,CoW 保护在写入前完成,shared page 永远不被污染。
2.2 断裂点在哪里?
问题出在两次偏移解析之间。
第一次校验发生在 tcf_pedit_act() 计算 nkeys 时,它检查所有 key 的 offset、val、mask 组合后的总写入范围是否合法。此时对于某些特殊的 key 类型(偏移在运行时依赖实际数据包头内容才能确定),内核使用的是一种「预留槽」机制——先分配了一个最大范围,但没有精确锁定每个 key 的最终落点。
第二次,也就是实际写入时,这些 key 的偏移被运行时解析(例如基于 VLAN tag 层数动态计算)。如果运行时解析出的偏移超出了第一次校验时预留的私有副本范围——
写入操作就越界落回了共享的 page cache 页。
用一句话讲:
它量好尺寸才去借西装,结果扣子缝歪了,扎到了别人的皮肤上。
2.3 投毒链条
攻击者的完整攻击链:
1. 创建用户命名空间 → 获得 namespace-local CAP_NET_ADMIN2. 加载 act_pedit 模块(如果未加载)3. 打开 /bin/su(setuid root)→ 页面进入 page cache(共享状态)4. 构造 tc pedit 规则,精确计算偏移使写入落在 /bin/su 的内存页中5. 触发规则,向 cached page 注入 shellcode / 修改逻辑6. 执行被投毒的 /bin/su → 内核看到 setuid bit + 文件未修改(磁盘是干净的) → 实际执行的是被污染的内存页中的代码 → 获得 root shell精妙之处:它不需要写 /etc/passwd、不需要改 sudoers、不触发任何文件系统级别的审计日志。整个攻击在内存中完成,文件哈希不变,AIDE/Tripwire 静默。
三、为什么这次特别危险?
3.1 入口门槛低
过去的 page-cache 漏洞往往需要特定条件:
- Dirty Pipe 需要 pipe + splice 的配合
- DirtyClone 需要 io_uring 支持
而 pedit COW 的入口是 非特权用户命名空间 + 可加载的内核模块。在主流发行版的默认配置下,这两项都是开启的:
| 发行版 | unprivileged userns | act_pedit 可用 | 默认可被利用? |
|---|---|---|---|
| RHEL 8/9/10 | ✅ 默认开启 | ✅ 内核内置或可加载 | ✅ |
| Debian 11/12/13 (trixie) | ✅ 默认开启 | ✅ 可加载 | ✅ |
| Ubuntu 18.04-24.04 | ✅ 默认开启 | ✅ 可加载 | ✅(24.04 需绕 AppArmor) |
| Ubuntu 26.04 | ✅ 内核支持 | ✅ 可加载 | ⚠️ AppArmor 默认阻断 userns |
3.2 检测盲区
传统检测手段几乎全部失效:
- 文件完整性监控(AIDE/Samhain/Tripwire):磁盘文件未被修改 → 通过
- auditd 文件访问日志:只监控 syscall 层面的 open/read/write → 不覆盖 page cache 操作
- 杀毒软件:无法扫描内核态的内存写入
- EDR/HIDS:除非 hook 了内核函数,否则看不到
tcf_pedit_act内部的越界写入
唯一有效的检测是行为审计:一个非特权用户突然执行了 tc 命令并带着 pedit action,这本身就是异常信号。但攻击者可以在投毒后清理 tc 规则,痕迹只留在一瞬间。
3.3 时间线令人不安
2026-05-23 补丁出现在 netdev mailing list(标注为"数据损坏修复")2026-06-16 CVE 编号分配(补丁合入主线)2026-06-17 公开 PoC 发布2026-06-26 The Hacker News 报道2026-06-29 本文发布时,大量发行版仍未推送修复3 周——从补丁公开到武器化利用。如果一个漏洞的补丁在 mailing list 上躺了三周而无人重视,那它不是被遗忘,而是被忽视了。
四、攻防实操
4.1 复现环境(PoC 已验证)
根据公开 PoC 的测试结果:
- RHEL 10:直接提权成功,无任何阻断
- Debian 13 (trixie):直接提权成功
- Ubuntu 24.04:需通过 AppArmor profile 路由(利用仍可用的 profiles),提权成功
- Ubuntu 26.04:AppArmor 阻断默认 user namespace 创建,exploit 在此环境下失败(但内核本身仍然脆弱)
4.2 快速自查
# 1. 检查内核版本uname -r
# 2. 检查 act_pedit 模块是否可加载(存在 .ko 文件即危险)find /lib/modules/$(uname -r) -name '*act_pedit*'
# 3. 检查 unprivileged user namespaces 状态# Debian/Ubuntu:cat /proc/sys/kernel/unprivileged_userns_clone# RHEL/CentOS:cat /proc/sys/user/max_user_namespaces
# 4. 综合判定:# - 内核版本 < 修复版本(各发行版自行查询)# - act_pedit 模块可用(.ko 存在或已加载)# - unprivileged userns = 1(或 max_user_namespaces > 0)# → 系统存在被利用条件4.3 立即处置:两条防线,双管齐下
防线一:阻断 act_pedit 模块加载
# 检查模块是否已加载lsmod | grep act_pedit
# 永 久阻止加载echo 'install act_pedit /bin/true' | sudo tee /etc/modprobe.d/disable-act_pedit.conf
# 如果已加载,立即卸载sudo rmmod act_pedit 2>/dev/null此项操作不影响正常网络功能——除非你主动使用 tc pedit 修改数据包头。绝大多数服务器不需要此功能。
防线二:禁用非特权用户命名空间
# Debian/Ubuntu(立即生效 + 持久化)sudo sysctl -w kernel.unprivileged_userns_clone=0echo "kernel.unprivileged_userns_clone = 0" | sudo tee /etc/sysctl.d/99-disable-userns.conf
# RHEL/CentOSsudo sysctl -w user.max_user_namespaces=0echo "user.max_user_namespaces = 0" | sudo tee /etc/sysctl.d/99-disable-userns.conf⚠️ 警告:禁用 unprivileged userns 会破坏 rootless 容器(Podman rootless、Docker rootless)、部分 CI 沙箱、以及基于命名空间隔离的浏览器沙箱(Chromium/Firefox)。在生产环境操作前务必评估影响。
防线三:升级内核并重启
这是唯一彻底的修复方案。对于无法立即重启的系统,前两条防线是救命稻草。
# Ubuntu/Debiansudo apt update && sudo apt install linux-image-generic -ysudo reboot
# RHEL/CentOSsudo yum update kernel -ysudo reboot4.4 事故后的取证思路
如果怀疑已被入侵:
# 1. 检查 tc 规则中是否有异常的 pedit actiontc -s filter show dev lo 2>/dev/nulltc -s filter show dev eth0 2>/dev/null
# 2. 清除页面缓存(会丢掉攻击痕迹,但至少确保当前运行的二进制是干净的)echo 3 | sudo tee /proc/sys/vm/drop_caches
# 3. 检查是否有异常 root shell 进程(如 /bin/su 的不正常子进程)ps auxf | grep -v grep | grep -E 'su|bash.*root'
# 4. 全面取证:dump 内存、检查 auditd 日志时间线上的 tc 命令# 但因攻击在内存中完成,磁盘取证价值有限。# 原则:发现被利用 → 视为完全失陷 → 重装系统,不是清理。五、写在最后:从补丁到武器,中间到底差了什么?
这个漏洞最让人脊背发凉的,不是它的技术复杂度(实际上比 Dirty Pipe 更简单),而是信息差。
5 月 23 日,补丁出现在 netdev mailing list,标题平淡无奇,归类为「数据损坏修复」。没有人标注 Security、没有人分配 CVE、没有人拉响警报。
6 月 16 日,补丁合入主线,CVE 下发。
6 月 17 日,exploit 发布。
从 mailing list 到 weaponized PoC,跨度三周。而直到 6 月底,大量生产系统依然暴露。
这不是 0day,这是 -21day——防御方有 21 天的时间窗口,但没有人认出这是一道裂缝。
安全社区需要反思的不只是代码质量,更是对补丁中「无关紧要的修复」的嗅觉。
内核 page-cache 写入路径上的任何校验变更——哪怕是「修复数据损坏」——都应该自动触发安全团队的审视。因为在这个领域,数据损坏和权限提升之间的距离,往往只隔着一个 setuid 位。
六、资源链接
- NVD 页面:CVE-2026-46331
- Red Hat 安全公告:RHSB-2026-008
- Debian 安全追踪:CVE-2026-46331
- Ubuntu 安全公告:CVE-2026-46331
- 公开 PoC:github.com/sgkdev/packet_edit_meme
- 原始补丁:netdev mailing list
- The Hacker News 报道:New Linux pedit COW Exploit Enables Root Access by Poisoning Cached Binaries
联系方式 & 交流群
联系方式 & 交流群
- 微信:gzs-47
进微信群请联系博主,各位觉得文章对你有帮助的话可否打赏一些呀~
文章分享
如果这篇文章对你有帮助,欢迎分享给更多人!














