- Alexander Popov (@a13xp0p0v) vừa công bố một bài phân tích cực kỳ chi tiết về struct pipe_buffer — chỉ 40 byte nhưng mở ra 4 lớp primitive cho kernel exploit: Dirty Pipe, control-flow hijack, AARW, và PageJack.
- Đọc kỹ để hiểu vì sao chỉ cần corrupt 8 byte là đã có AARW ổn định.
TL;DR
Alexander Popov (@a13xp0p0v) vừa xuất bản bài viết "Some notes on the security properties of the pipe_buffer kernel object" ngày 20/04/2026, tổng hợp các thí nghiệm trong dự án kernel-hack-drill của ông. Bài viết giải mã vì sao struct pipe_buffer — chỉ 40 byte — lại là mục tiêu heap-spray số một của giới exploit Linux kernel hiện đại, và hé lộ một chi tiết trong anon_pipe_get_page() khiến primitive AARW trở nên tự khuếch đại.

Có gì mới
Bài phân tích không công bố CVE, mà là một tài liệu kỹ thuật dày đặc — Popov gọi là "notes" — ghi lại những gì ông học được khi build exploit cho CVE-2024-50264 (lỗ hổng mptcp) bằng harness kernel-hack-drill. Ba đóng góp đáng chú ý:
- Liệt kê đầy đủ 4 primitive có thể dựng từ
pipe_buffer: Dirty Pipe (CVE-2022-0847), control-flow hijack quaops, arbitrary kernel read/write quapage+offset+len, và PageJack — chỉ cần partial overwrite byte thấp của con trỏpagelà đã redirect được sang page của pipe khác. - Giải thích tại sao
anon_pipe_get_page()cache page trongpipe_inode_info.tmp_page[2], khiếnpipe_bufferthứ hai tự động kế thừa con trỏ bị corrupt — bạn corrupt 1 lần, hưởng nhiều lần. - Đưa ra trick thực dụng: gọi
daemon()để giữ pipe mở, tránh việc đóng pipe trả page bị corrupt lại cho buddy allocator → panic ngẫu nhiên.
Vì sao quan trọng
Từ Dirty Pipe 2022 tới giờ, pipe_buffer đã trở thành "universal target" cho exploit Linux kernel. Nhưng tài liệu công khai gộp đủ 4 primitive + các chi tiết slab spray + quota tuning + tính ổn định post-exploit thì rất hiếm. Bài của Popov chính là tài liệu field manual đó. Với defender, nó là checklist để kiểm tra hardening (CONFIG_BUG_ON_DATA_CORRUPTION, SLAB_FREELIST_HARDENED, RANDOM_KMALLOC_CACHES). Với researcher, nó là blueprint cho các CVE tiếp theo chạm vào slab kmalloc-1k.
Fact kỹ thuật
Layout struct pipe_buffer trên kernel v6.18:
struct pipe_buffer {
struct page *page; /* 0 8 */
unsigned int offset; /* 8 4 */
unsigned int len; /* 12 4 */
const struct pipe_buf_operations *ops; /* 16 8 */
unsigned int flags; /* 24 4 */
long unsigned int private; /* 32 8 */
}; /* size 40, cachelines 1 */| Thông số | Giá trị mặc định | Ý nghĩa cho attacker |
|---|---|---|
| Pipe capacity | 65,536 byte | Cấp 16 pipe_buffer = 640 byte/pipe |
| Slab cache landing | kmalloc-1k | Ít nhiễu, dễ spray |
pipe-user-pages-soft | 16,384 page | Vượt limit → pipe sau bị co lại, fragment slab |
pipe-max-size | 1,048,576 byte (256 page) | Có thể resize để rơi vào slab khác |
| Min capacity | 4,096 byte (1 page) | Floor khi resize |
Toán spray: 1024 pipe × 16 buffer = 16,384 page — vừa đúng ceiling soft limit. Nắm con số này thì tune exploit ổn định hơn nhiều.
So sánh 4 primitive
| Primitive | Field corrupt | Kết quả | Ví dụ CVE |
|---|---|---|---|
| Dirty Pipe | flags | Ghi được file read-only | CVE-2022-0847 |
| Control-flow hijack | ops (function table) | RIP control → kROP | Lớp kernel RCE cổ điển |
| AARW | page + offset + len | Đọc/ghi tuỳ ý kernel memory | Dùng trong chuỗi CVE-2024-50264 |
| PageJack | Partial page (byte thấp) | Trỏ sang page của pipe khác → page UAF | Primitive mới Popov nhấn mạnh |
Use case: AARW hiệu quả
Popov mô tả quy trình chuẩn:
- Resize pipe để rơi vào slab cache mục tiêu.
- Ghi full page vào pipe.
- Corrupt con trỏ
pipe_buffer.pageđầu tiên. read()→ leak page kernel về userspace.- Sửa nội dung,
write()→ đẩy ngược vào kernel memory.
Điểm lợi: vì anon_pipe_get_page() cache page đã release trong tmp_page[2], pipe_buffer thứ hai sẽ nhận lại đúng con trỏ bị corrupt khi write() quay lại pipe. Muốn quét nhiều page khác nhau thì cycle qua đủ 16 pipe_buffer giữa các lần ghi, tránh giá trị cache ghi đè target mới.
Giới hạn & mitigation
pipe-user-pages-hardchặn spray vô hạn từ unprivileged user.- Bảng
pipe_buf_operationsnằm trong read-only kernel data — control-flow hijack vẫn cần kASLR leak trước. - Hardening hiện đại (
CONFIG_BUG_ON_DATA_CORRUPTION,SLAB_FREELIST_HARDENED,RANDOM_KMALLOC_CACHES) làm spray ồn hơn nhưng không vô hiệu hoá primitive. - Đóng pipe có
pagecorrupt → trả page kernel vào buddy allocator → panic. Fix:daemon()giữ tiến trình sống, pipe mở. - Bài viết không phải disclosure — không có patch mới, các fix Dirty Pipe (5.16.11 / 5.15.25) vẫn là mốc phòng thủ cũ.
Tiếp theo
Popov bóng gió về một hướng mới: page-reclamation attack — lạm dụng hành vi buddy allocator khi pipe page được giải phóng có kiểm soát. kernel-hack-drill vẫn là sandbox chính để ông thử nghiệm, nên kỳ vọng các bài tiếp theo sẽ đào sâu vector này.
Nguồn: a13xp0p0v.github.io, kernel-hack-drill & CVE-2024-50264, xairy/linux-kernel-exploitation.
