-
-
[原创]CVE-2022-0847 Dirty Pipe 漏洞原理深度分析 近年来最"干净"的内核提权漏洞之一
-
发表于: 1小时前 54
-
这个漏洞的本质是: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 所有内核 |
// 内核中的 pipe_buffer 结构体
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内核攻防全技术栈,打造具备自动化能力的内核开发高手。
赞赏
他的文章
赞赏
雪币:
留言: