-
-
[原创]CVE-2022-0847 Dirty Pipe 漏洞原理深度分析 近年来最"干净"的内核提权漏洞之一
-
发表于:
2026-6-17 19:25
1607
-
[原创]CVE-2022-0847 Dirty Pipe 漏洞原理深度分析 近年来最"干净"的内核提权漏洞之一
这个漏洞的本质是:pipe_buffer 结构体中的 flags 字段未被正确初始化,导致通过 splice() 从文件引入的页面缓存(page cache)被错误地标记为"可合并写入"(PIPE_BUF_FLAG_CAN_MERGE),从而允许后续的 write() 直接写入该页面缓存,修改任意只读文件的内容。
当此标志被设置时,内核认为"这个 pipe_buffer 可以追加写入数据",而不是分配新的 buffer。
补丁commit: 9d2231c5d74e (Linux 5.16.11, 5.15.25, 5.10.102)
这是近年来最"干净"的内核提权漏洞之一 — 无需绕过任何保护机制,一次成功,无副作用。
| 特性 |
说明 |
| 利用可靠性 |
100%确定性,无需竞态/堆喷 |
| 利用复杂度 |
极低,~100行代码 |
| 前置条件 |
仅需文件可读 |
| 权限要求 |
普通用户即可 |
| 检测难度 |
不触发 SELinux/审计 |
| 影响范围 |
5.8 - 5.16.11 所有内核 |
struct pipe_buffer {
struct page *page;
unsigned int offset;
unsigned int len;
const struct pipe_buf_operations *ops;
unsigned int flags;
unsigned long private;
};
flags 中的关键标志位:
PIPE_BUF_FLAG_CAN_MERGE = 0x10
┌─────────────────────────────────────────────────────┐
│ prepare_pipe(p) │
│ │
│ 1. pipe(p) 创建管道 │
│ │
│ 2. 填满管道(写满所有 pipe_buffer) │
│ ┌──────┬──────┬──────┬──────┬───────────────┐ │
│ │ buf0 │ buf1 │ buf2 │ ... │ bufN │ │
│ │flags=│flags=│flags=│ │flags= │ │
│ │MERGE │MERGE │MERGE │ │MERGE │ │
│ └──────┴──────┴──────┴──────┴───────────────┘ │
│ 写入时内核自动设置 PIPE_BUF_FLAG_CAN_MERGE │
│ │
│ 3. 读空管道(drain) │
│ - 所有 pipe_buffer 被"释放"回环形队列 │
│ - 但 flags 字段 **没有被清零**! │
│ - flags 仍然保留 PIPE_BUF_FLAG_CAN_MERGE │
│ │
│ 结果:管道为空,但下一个被使用的 pipe_buffer │
│ 仍带有残留的 CAN_MERGE 标志 │
└─────────────────────────────────────────────────────┘
[内核课程]《Windows内核攻防实战》!从零到实战,融合AI与Windows内核攻防全技术栈,打造具备自动化能力的内核开发高手。