Skip to content

Page UAF

Dangling reference'ın freed bir slab object yerine freed bir page'i gösterdiği bir use-after-free — yani reclaim eden allocation herhangi bir page-backed object olabilir, bu da bug'ı type'tan bağımsız ve per-cache hardening'e karşı bağışık kılar.

Mechanism

Note

Object-level bir UAF, pointer'ı freed bir slab object'e sarkıtır; page UAF ise reference'ı freed bir page'e sarkıtır. Bunu güçlü kılan invariant şu: bir slab bütünüyle free edildiğinde (ya da bir page * tutan bridge object corrupt edildiğinde), arkadaki page kmem_cache'ten ayrılır ve buddy allocator'a döner, burada artık typed değildir. O page'i bir sonraki isteyen subsystem — farklı bir cache için slab refill, bir pipe buffer, bir page table — onu yeniden kullanır. Dolayısıyla dangling page reference, orijinal bug'ın cache'i ne olursa olsun, attacker'ın seçtiği bir object'le örtüşür. Bu, object-level reuse'u engelleyen freelist randomization, RCU grace period'ları ve cache isolation'ı atlatır.

Bir "bridge object", kendisi bir page pointer'ı sahiplenen bir slab object'tir. Phrack writeup'ı kanonik örnek olarak struct pipe_buffer array'ini (her elemanı bir page field'ı taşır) gösteriyor: allocation cache'i pipe boyutuna göre değişir — F_SETPIPE_SZ ile seçilen array boyutuna bağlı olarak kmalloc-96/128/192 ya da kmalloc-1k içine düşer (sizing detayları için bkz. pipe-buffer grooming), dolayısıyla yalnızca kmalloc-192 demek predictability'yi olduğundan basit gösterir. page pointer'ını corrupt edip komşu bir page'i alias et, o page'i bir bridge üzerinden free et ama ikinci bir bridge dangling reference'ı korurken — page artık UAF'tir.

Walkthrough

/* Conceptual page-UAF via a pipe_buffer bridge object (Phrack 71). */

/* 1. Allocate two pipes; each pipe_buffer carries a `page *`. */
int a[2], b[2]; pipe(a); pipe(b);

/* 2. Use the bug to corrupt pipe_buffer.page in one buffer so two
      pipe_buffers reference the SAME physical page. */

/* 3. close() one pipe -> its pipe_buffer is released and the shared
      page is returned to the buddy allocator ("the entire page to be
      freed ... returned to the buddy allocator for future slab
      allocations"). The other pipe still holds a dangling reference. */
close(a[0]); close(a[1]);

/* 4. Reclaim: spray a victim object that lands on the freed page.
      Read/write it through the surviving (dangling) pipe. */

Page bir kez dangling olduğunda, reclaim hedefi sonuna kadar açıktır:

/* exhaust existing slab caches so the next same-size allocation must
   carve a fresh page off the buddy allocator -> it grabs the freed page */
spray_until_slab_empty();
spray_victim_objects();        /* e.g. struct cred: set cred.uid = 0 */
read_back_via_dangling_pipe(); /* leak/overwrite overlapped victim */
v5.14 sonrası incelik

Writeup, Linux v5.14'ten sonra pipe_buffer'ın dedike bir kmalloc-cg cache'ine izole edildiğini, dolayısıyla bridge object ile victim'in artık varsayılan olarak bir cache'i paylaşmadığını belirtiyor. Bu, bir cross-cache adımını zorunlu kılar: bridge'in slab'ını tamamen free et ki page'i buddy allocator'a düşsün, ardından farklı bir cache'ten victim type ile reclaim et.

Warning

Reclaim order'a ve basınca duyarlıdır: freed page victim'e ancak spray, slab page ile aynı order, migrate type ve PCP/NUMA state'inde bir allocation sürerse yeniden hizmet eder. İlgili cache'i spray'lemeden önce tüket, yoksa page asla hedef allocation'ına dönmez.

Detection

Stale bir reference üzerinden okunup yazılan freed bir page tutarsız page state üretir; KASAN orijinal page free/use uyuşmazlığını işaretler. Runtime'da, hemen ardından ilgisiz bir page-backed type allocation'larının geldiği slab-cache exhaustion patlamaları davranışsal bir sinyaldir.

Mitigation

  • Page/slab isolation (SLAB_VIRTUAL, dedike virtual range'ler) freed bir slab page'inin yabancı-type bir page olarak remap edilmesini engeller, cross-type reclaim'i kırar.
  • Hardened pipe_buffer / bridge-object yerleşimi ve freelist hardening, en baştan page *'ı corrupt etmenin maliyetini yükseltir.

Ayrıca bkz. page spray, PageJack page-level UAF, udmabuf driver page UAF.

References