Arbitrary read/write via pipe_buffer¶
Bir
struct pipe_buffer'ınpagepointer'ını corrupt et ki sıradan piperead()/write()keyfi bir kernel physical page'i üzerinde çalışsın — tam sayfalık, keyfi bir R/W primitive'i.
Info
Bu doc R/W primitive'inin kendisine ve anon_pipe_get_page()/anon_pipe_put_page()
page-reuse davranışına (write-back yoluyla persistence) odaklanır. Corrupt edilmiş page'i
bir heap target'ının struct page'ine çeviren vmemmap aritmetiği ve F_SETPIPE_SZ
cross-cache grooming'i için tamamlayıcı pipe-buffer-hijack'e bak —
aynı corruption'ın data-only, targeting'e odaklı görünümü.
Mechanism¶
Note
Bir pipe, her biri bir struct page *page ile o page'e bir offset/len penceresine
referans veren bir struct pipe_buffer dizisi tutar. Pipe read()/write(),
page[offset .. offset+len] üzerinde çalışır. Bir attacker page pointer'ını corrupt
ederse (bir UAF ile ya da pipe_buffer dizisine bir overflow ile), pipe I/O keyfi bir
physical page'e yönlendirilir — kernel keyfi read ve write. Bunun yerine ops'u (→
anon_pipe_buf_ops) corrupt etmek control-flow hijack verir; flags'i
(PIPE_BUF_FLAG_CAN_MERGE) corrupt etmek ise Dirty Pipe sınıfıdır.
Obje (40 byte):
struct pipe_buffer {
struct page *page; /* off 0 <-- corrupt for R/W */
unsigned int offset; /* off 8 */
unsigned int len; /* off 12 */
const struct pipe_buf_operations *ops; /* off 16 <-- corrupt for RIP */
unsigned int flags; /* off 24 */
unsigned long private; /* off 32 */
};
Default 16-buffer'lık pipe dizisi 16 * 40 = 640 byte'tır → kmalloc-1024.
Walkthrough¶
int pfd[2];
pipe(pfd);
write(pfd[1], pagebuf, 0x1000); /* populate a pipe_buffer.page */
/* ... UAF/overflow overwrites pipe_buffer.page with a target kernel page ... */
read(pfd[0], leak, 0x1000); /* leaks a full page of kernel memory */
/* or write(pfd[1], data, n) to write the target page */
anon_pipe_get_page(), page'leri pipe_inode_info.tmp_page[2]'den çeker ve
anon_pipe_put_page(), (corrupt edilmiş) pointer'ı yeniden kullanım için geri saklar — bu
da sonraki pipe operasyonlarında keyfi kernel memory'sine write-back yapmayı mümkün kılar.
ops'u sahte bir anon_pipe_buf_ops table'ına işaret ettirmek, bir
function-pointer/control-flow target'ı sağlar.
Warning
Corrupt edilmiş bir pipe'ı kapatmak, saldırılan page'i page allocator'a geri verir ve
öngörülemeyen kernel memory reuse'una yol açar — kernel'i crash'leyebilen ya da bir
forensic sinyal bırakabilen bir cleanup mayını. Kapatmadan önce orijinal page'i geri
yükle ya da pipe'ı hiç kapatma.
Mitigation¶
Bu primitive'i hedefleyen özel bir mitigation yoktur; savunma, başlangıçtaki pipe_buffer
corruption'ını engellemeye (slab freelist hardening, freelist-pointer randomization, cache
isolation) ve flags/uninitialized varyantı için Dirty Pipe fix'ine dayanır.