Dirty PageTable page-table data-only attack¶
Freed bir heap object'ini bir donanım page-table sayfasıyla overlap ettir, sonra bir PTE'yi corrupt ederek arbitrary physical read/write elde et — KASLR, SMAP, SMEP ve CFI'yı bypass eden data-only bir primitive.
Mechanism¶
Dirty Pagetable, bir heap UAF / double-free / OOB'yi arbitrary physical memory read/write'a çevirir; bunu freed bir object'i bir page-table sayfasıyla overlap ettirip ardından bir page-table entry (PTE) corrupt ederek yapar. İşin püf noktası allocation provenance'tır: last-level user page table'lar bir kmalloc slab'inden gelmez — bunlar __pte_alloc() → pte_alloc_one() üzerinden buddy/page allocator'dan gelir, her PTE table için bir adet 4 KB sayfa.
Note
Bir PTE, upper bit'lerinde bir physical address ile birlikte _PAGE_PRESENT ve _PAGE_RW dahil flag'leri encode eder. Bir PTE'nin physical-address alanını overwrite ederek (ya da increment-only primitive'lerle increment ederek) _PAGE_PRESENT | _PAGE_RW set kalırken, attacker kendi userspace virtual sayfalarından birini attacker'ın seçtiği physical memory'ye yönlendirir — kernel .data/code ya da başka bir process'in page table'ı — ve böylece arbitrary physical R/W elde eder. Hiçbir kernel pointer veya code dereference edilmediğinden KASLR, SMAP/PAN, SMEP ve CFI'nın hepsi bypass edilir.
Walkthrough¶
Nicolas Wu'nun writeup'ına göre chain şöyledir:
1. Trigger the UAF/double-free on a victim object in some slab.
2. Drain the rest of that slab's objects so the slab page is freed
back to the page allocator (cross-cache setup).
3. Spray user page tables: mmap many regions and touch them so
__pte_alloc()/pte_alloc_one() pulls the freed page as a PTE table.
The dangling/UAF object now overlaps PTE entries.
4. Use the bug's write/increment primitive on the overlapped PTE:
set the physical-address field to a target physical page and keep
_PAGE_PRESENT | _PAGE_RW.
5. Read/write the corresponding userspace virtual address — it now
aliases the chosen physical memory.
6. Locate the right PTE / leak its value with helper objects
(e.g. seq_operations via procfs), correlating leaked PTE values
with known physical addresses.
Increment-only bug'lar için, struct file'ın f_count'u gibi alanlar (dup()/fork() ile artırılan) bir PTE ile overlap edecek şekilde konumlandırılır; böylece tekrarlanan syscall'lar physical-address alanını yukarı doğru yürütür. Beklenen sonuç: stabil arbitrary physical read/write; kernel code'u patch'leyerek ya da credential data'sını overwrite ederek root'a yükselt.
Mitigation¶
Tartışılan mitigation'lar: kernel physical-address randomization, read-only user page table'lar ve page-table integrity'sinin hypervisor/TrustZone ile zorlanması. SLAB_FREELIST_HARDENED slab-grooming adımını zorlaştırır ama engellemez.