CROSS-X cross-cache attack¶
Klasik tekniğin başarısız olduğu modern kernel'lerde bile bir victim slab'i page allocator'a geri zorlamak için per-CPU partial list'i overflow eden, genelleştirilmiş ve kararlı bir cross-cache "recycling" stratejisi.
Mechanism¶
CROSS-X (CCS 2025, Kim/Song/Yun) "recycling phase"i — vulnerable slab'i page allocator'a geri zorlamayı — formalize eder ve uzun süredir kullanılan public tekniğin modern kernel'lerde başarısız olduğunu gösterir. SLUB modeli: kmem_cache → per-CPU kmem_cache_cpu (aktif c->slab, c->freelist, per-CPU partial c->partial) ve per-node kmem_cache_node (n->partial); list uzunlukları cpu_partial (diğer adıyla cpu_partial_slabs) ve min_partial ile sınırlandırılır. Bir slab, zaten-dolu bir per-node partial list'te otururken bir object'i free etmek onu boş yaptığında yalnızca o zaman page allocator'a discard edilir.
Slab'in recycling yolunu kavramsal olarak (boyutlar/limit'ler kernel ve cache'e göre değişir):
active slab per-CPU partial per-node partial page
(c->slab) (c->partial) (n->partial) allocator
+---------+ full +---+ +---+ +---+ >cap +---+ +---+ ... +---+ empty
| objs... | ---------> | | | | | | -----> | | | | ... | | --------> discard
+---------+ free→push +---+ +---+ +---+ overflow +---+ +---+ +---+ last free
len ≤ cpu_partial len ≤ min_partial (slab boş olunca)
recycling = victim slab'i bu zincir boyunca page allocator'a kadar zorlamak;
her node hop yalnızca önceki list dolu (overflow) olduğunda gerçekleşir.
Note
Buldukları root cause: v5.15 → v6.1 arasında cpu_partial ve min_partial arasındaki boyut ilişkisi generic cache'lerin ~yarısı için tersine döndü (örn. kmalloc-1024/2048 (cpu_partial, min_partial) = (3, 5) oldu). min_partial > cpu_partial olduğu için klasik "Partial Free" stratejisi artık per-node partial list'i overflow edemez ve deterministik %0 recycling verir. CROSS-X'in Complete Free stratejisi, bu tersine dönme durumlarında bile per-CPU partial list'i overflow etmek için ekstra slab allocation'ları ekler. Hibrit bir SLUBStick + Complete Free, müdahale eden allocation'ları filtrelemek için slab allocation sırasında bir timing side-channel kullanır.
Walkthrough¶
CROSS-X dört public recycling stratejisini ve sınırlarını gözden geçirir:
- Naïve — çok sayıda object allocate et, hepsini free et, recycling için umut et; migration timing'inde başarısız olur.
- Partial Free (Jann Horn, CVE-2020-29661 exploit'i) — defragment et,
(cpu_partial+1)slab allocate et, victim'i iki ekstra slab arasına yerleştir, slab'leri per-CPU partial list'e itmek için free et, sonra per-node partial'ı overflow edip victim slab'i discard etmek için her slab'de bir object free et. - Interleaving Cores — cross-CPU varyantı (bir core'un aktif slab'ini doldur, başka bir core'a pinle, slab'i o core'un per-CPU partial list'ine taşımak için free et).
- Timing Side-Channel (Pspray / SLUBStick) — slab creation'ı tetikleyen allocation ölçülebilir biçimde daha uzun sürer.
346 aday object arasından CROSS-X'in ObjectFuzzer/ObjectEvaluator/ObjectMatcher'ı yedi çok yönlü target object belirledi (düşük same-cache ve same-order gürültüsü): timerfd_ctx, io_ring_ctx, msg_msg, pipe_inode_info, pipe_buffer, fsnotify_group, shmid_kernel.
Sonuçlar
Sentetik vakalar artı dokuz gerçek-dünya CVE'si üzerinde değerlendirildi: idle'da >%99 başarı, busy'de %85. Complete Free v5.15/v6.1/v6.6 boyunca tüm cache'ler için çalıştı; SLUBStick + Complete Free dokuz cache'te %100'e ve iki cache'te daha %99.97'ye ulaştı (v6.1 idle).
Mitigation¶
Makaleden: RANDOM_KMALLOC_CACHES yalnızca hafif gürültü ekler; SLAB_BUCKETS msg_msg/memdup_user'ı sınırlandırır ama netlink'i (nla_memdup/nla_strdup), eBPF loader'larını ve memdup_user_nul'u fence'in dışında bırakır ve hâlâ SLUB internal'larını paylaşır. SLAB_VIRTUAL recycling phase'ini doğrudan bloke ederdi ama mainline değildir.