Skip to content

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.

References