Page-level heap feng shui¶
Belleği buddy allocator'da 4 KB physical page'ler granülaritesinde (tek tek slab object'ler değil) grooming ederek, free edilen bir page'in attacker'ın corrupt etmek istediği slab cache veya object tarafından deterministik şekilde reclaim edilmesini sağlamak.
Mechanism¶
Note
Klasik slab feng shui, object'leri bir slab'in içinde yeniden düzenler. Page-level
feng shui bir seviye aşağıda çalışır: buddy (page) allocator'da tüm 4 KB page'leri
düzenler. İstismar ettiği invariant SLUB↔buddy sınırıdır: bir slab cache belleğe ihtiyaç
duyduğunda buddy allocator'dan bir page (veya compound page) ister; bir slab'in page'leri
boşaldığında onları buddy allocator'ın free list'lerine / per-CPU page (PCP) list'lerine
geri verir. Buddy allocator order başına ve per-CPU LIFO-vari olduğu için, page'lerin hangi
sırayla free edilip yeniden talep edildiğini kontrol eden bir attacker, belirli bir free
edilmiş page'i hangi slab cache'in (veya hangi page-mapping object'inin) sahipleneceğini
öngörebilir — CONFIG_SLAB_FREELIST_RANDOM'dan bağımsız olarak, ki o yalnızca bir slab
içindeki object order'ını randomize eder, cache'ler arası page order'ını değil.
İki baskın kullanım bug class'ına göre farklılaşır (Phrack 71 "novel page-UAF exploit strategy"e göre):
- OOB feng shui: bir page'i vulnerable object'lerle doyur, sonra slab sonraki page'i isteyecek şekilde target object'leri allocate et. Page 1'deki son vulnerable object, page 2'deki ilk target object'e physically adjacent olur, böylece bir overflow page sınırını aşıp target'a geçer.
- UAF / page-UAF feng shui: vulnerable object'in yanına bir "bridge" object — bir
struct page *sahibi olan bir slab object'i — yerleştir; bir dangling reference hayatta kalırken page'in kendisi buddy allocator'a dönecek şekilde corrupt et veya free et, sonra o page'i victim slab/object ile reclaim etmek için yeniden spray'le.
Warning
Page-level grooming order- ve timing-duyarlıdır: PCP list'leri per-CPU'dur, bu yüzden
attacker genellikle tek bir CPU'ya pin'ler (sched_setaffinity) ve target allocation
az önce free edilen page'i çeksin diye PCP list'lerini drain/refill eder. Aşağıdaki
sayılar target'a özgüdür — onları hardcode etme.
Walkthrough¶
Genel OOB page-boundary groom'u (kavramsal, Phrack stratejisinden):
/* 1. Pin to one CPU so per-CPU page (PCP) lists are deterministic. */
cpu_set_t set; CPU_ZERO(&set); CPU_SET(0, &set);
sched_setaffinity(0, sizeof(set), &set);
/* 2. Saturate the current slab page with vulnerable objects so the
* cache is forced to request a fresh page from the buddy allocator. */
for (int i = 0; i < OBJS_PER_PAGE; i++)
alloc_vulnerable_object();
/* 3. Allocate the target object: the slab now serves it from the page
* that immediately follows the vulnerable object's page. The last
* vuln object on page N is adjacent to the first target on page N+1. */
alloc_target_object();
/* 4. Trigger the out-of-bounds write: it spills off the end of page N
* into the target object at the start of page N+1. */
trigger_oob_write();
page-UAF varyantı için "bridge" object'leri, bir slab'in altından bir page'i free etmeni sağlar. Phrack'in stratejisi ve PageJack çalışması, bu page sahibi slab object'lerine dikkat çeker:
pipe_buffer->page (the pipe array, kmalloc-192 / kmalloc-1k by pipe size)
configfs_buffer->page (kmalloc-128)
bio_vec->bv_page (variable)
wait_page_queue->page (variable)
Böyle bir bridge object'i free etmek (veya pipe'ını kapatmak), backing 4 KB page'ini buddy
allocator'a geri verir; bu da onu sonraki spray'de dedicated bir slab cache'e (örn. cred
veya file cache) verebilir — bunu bir page-level UAF read/write primitive'ine çevirmek için
pagejack-page-level-uaf'e, reclaim adımı için
page-uaf / page-spray'e bak.
Cross-cache kırılganlığını neden es geçtiği
Geleneksel bir cross-cache attack, slab'in page'ini buddy allocator'a geri itmek için vulnerable object'lerin tüm bir slab'ini free eder, sonra onu farklı bir cache ile reclaim eder. Bu, slab'deki her object'i boşaltmayı ve page-reclaim heuristic'leriyle race etmeyi gerektirir, ki kırılgandır. Tek bir page sahibi bridge object üzerinden pivot eden page-level feng shui, tam olarak bir page'i deterministik şekilde free eder ve end-to-end güvenilirliği yükseltir (Phrack çalışması, case study'lerinde ~%75'ten %90–100'e geçtiğini raporlar). İncelenen CVE'ler arasında CVE-2023-5345, CVE-2022-0995, CVE-2022-0185 ve CVE-2021-22555 var.
Mitigation¶
CONFIG_SLAB_FREELIST_RANDOM yardımcı olmaz — intra-slab object order'ını randomize eder,
page order'ını değil. Google'ın önerdiği CONFIG_SLAB_VIRTUAL (bir virtual slab aralığını
farklı bir cache için asla yeniden kullanmayan virtually-mapped slab'ler), object-level
cross-cache'i yener, ama free edilen physical page'i bir dangling struct page * üzerinden
okuyan/yazan page-level UAF, physical page'ler üzerinde çalıştığı için (slab virtual adresleri
değil) onu hâlâ bypass edebilir.