Skip to content

Cross-cache via PCP massaging

Per-CPU page (PCP) freelist'ini şekillendir ki freed bir slab page'i seçilmiş bir victim cache'e deterministik olarak geri verilsin; böylece olasılıksal cross-cache'i kesin bir hâle getir.

Mechanism

Per-CPU Pageset (PCP) allocator'ı buddy allocator'ın önünde durur ve küçük-order'lı (order ≤ PAGE_ALLOC_COSTLY_ORDER = 3) page isteklerini global lock olmadan bir per-CPU freelist'ten karşılar. PCP state'i struct per_cpu_pages içinde yaşar (field'lar arasında lists[], count, batch, high bulunur), list index'leri order_to_pindex() tarafından (MIGRATE_PCPTYPES * order) + migratetype olarak hesaplanır. Boş bir PCP list'i rmqueue_bulk()/__rmqueue() üzerinden toplu olarak doldurulur (her seferinde batch page); high watermark'ının üzerinde free_pcppages_bulk() buddy free list'lerine geri taşar.

Note

Hem PCP hem de buddy free list'leri LIFO'dur — bu determinizm kaldıraçtır. Order-0 PCP list'ini massage ederek attacker, victim cache'in bir sonraki slab'e ihtiyacı olduğunda tam olarak hangi freed page'i alacağını kontrol eder ve cross-cache'i olasılıksal yerine deterministik hâle getirir.

Walkthrough

"Game of Cross Cache" (BH Asia 2024), gerçek bir Android vakası (victim = order-0 slab, attacker spray = order-3 kmalloc):

  • Dayanılan özellikler: "Order-0 allocation and releasing will use pcplist first, stack-liked way"; "Flushing for the pcplist: flush from tail."
  • Task'ı tek bir CPU'ya pinle (cpu#0).
  • Defragmentation — kısmen-free slab'leri free object'lerinden boşalt.
  • ~objs_per_slab * (1 + cpu_partial) object allocate et.
  • pcplist'e sığan maksimum sayıda order-0 page allocate et; böylece bunları release etmek "kesinlikle daha sonra pcplist'in flush'ını tetikleyecektir."
  • UNMOVABLE free_area'dan birkaç yüz fiziksel olarak bitişik order-0 page allocate et (gereksinimler: çok sayıda order-0 page, UNMOVABLE, "nispeten temiz"). Page-spray primitive'i pipe'tır (bir pipe'a yazmak bir order-0 page allocate eder; okumak free eder).
  • Her 8 page'de bir order-0 page release ederek "order-0 page hole'ları" oluştur ve pcplist'i attacker tarafından kontrol edilen hole'larla şekillendir.
  • Cross-cache workflow'unu tetikle ki freed victim slab bilinen bir hole'a insin, sonra yeni victim slab olarak reuse edilen hariç diğer tüm hole'ları (örn. ION page'leriyle) doldur → deterministik reuse.

Kavramsal şema — "hole" pattern'i ve LIFO reuse (boyutlar/sayılar gösterimseldir):

1) Bitişik order-0 page'ler spray edilir (pipe primitive ile):
   [P0][P1][P2][P3][P4][P5][P6][P7][P8] ... (UNMOVABLE, "temiz")

2) Her 8'de bir release → attacker-kontrollü "hole"'lar:
   [P0][P1][P2][P3][P4][P5][P6][HOLE] ... [HOLE] ...
                                  ^free            ^free
   PCP list (LIFO):  tail -> [HOLE_a][HOLE_b][HOLE_c] <- head

3) Cross-cache: freed victim slab page PCP'ye döner,
   bilinen bir hole'a "iner":
   [HOLE_a][HOLE_b][VICTIM_SLAB(freed)] <- bir sonraki alloc bunu çeker

4) Hedef hariç tüm hole'lar doldurulur (ör. başka allocation'larla):
   victim slab yeni cache'in slab'i olarak deterministik reuse edilir.
Akademik ele alış (PCPLOST, NDSS 2026)

"Cross-Cache Attacks for the Linux Kernel via PCP Massaging", "side channel'ları dikkatlice kullanarak kernel allocator'ının internal state'ini çıkarsayarak mainline mitigation'ları by-pass eden bir cross-cache memory massaging tekniği" tanımlar; bir cross-cache layout elde etmede >%90 başarı bildirir, 6 public CVE üzerinde doğrulanmıştır.

Mitigation

SLAB_VIRTUAL (araştırma) recycling/page-reuse adımını tamamen bloke ederdi. PCP-aware noise reduction ve unprivileged page-spray primitive'lerini devre dışı bırakmak deterministik massaging'in maliyetini yükseltir.

References