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.