Skip to content

Prefetch Side-Channel KASLR Break

The prefetch instructions execute in data-dependent time: their latency leaks whether a virtual address is mapped and which translation-cache level holds its mapping — an unprivileged oracle that locates the kernel direct map and text, defeating KASLR.

Editorial note (unverified)

Bu not mekanizmayı ağırlıklı olarak attack açısından anlatır; mitigation/ kategorisindeki yeri ve savunma-altitude'u editorial re-review bekliyor.

Mechanism

Neden çalışır

prefetch* bir hint'tir: software-prefetch instruction'ları (prefetchnta, prefetcht0/t1/t2, prefetchw) asla fault üretmez ve asla privilege kontrolü yapmaz — CPU bunları yok saymakta serbesttir. Ama bunları bedava yok saymaz. Hint'e göre hareket etmek için core, verilen virtual address'i translate etmek zorundadır ve bu translation TLB ve paging-structure cache'lerini walk eder (ya da hit eder). İşin miktarı — ve dolayısıyla instruction'ın yürütme süresi — translation'ın ne kadarının zaten cache'lendiğine ve address'in hiç map'li olup olmadığına bağlıdır.

Gruss ve diğerleri ("Prefetch Side-Channel Attacks", CCS 2016) bunu iki oracle'a dönüştürür. translation-level oracle, yalnızca timing'den, bir virtual address'in hangi seviyede (PML4/PDPT/PD/PT) map'li olmaktan çıktığını geri kazanır — bir process'in paging hiyerarşisini ve dolayısıyla ASLR/KASLR layout'unu yeniden inşa eder. address-translation oracle, kernel'in direct-physical map'inin tüm physical memory'yi alias'lamasını sömürür: bir user page'in (cache'lenebilir) direct-map alias'ını prefetch etmek o physical line için cache'i prime eder; bu da sonra user mapping üzerinden gözlemlenebilir — virtual→physical address'leri çözer ve direct map'i bulur. Timing farkı mimari olarak erişilemeyen mapping state'inden geldiği için ne SMAP, ne SMEP, ne de KASLR'nin randomize edilmiş base'i bunu gizler: map'li olan bir base'e "dokunmak" map'siz bir tahminden tutarlı şekilde daha hızlıdır.

Walkthrough

Çekirdek mantık, bir prefetch ardından ikinci bir erişimin rdtsc-parantezli timing'idir; ölçüm prefetch etrafında reorder edilmesin diye serialize edilmiştir.

1. Bir probe address'inin serialize edilmiş timing'i. Kavramsal olarak, her aday kernel base address için prefetch'in sonraki erişim süresini nasıl etkilediğini ölçersiniz:

// inaccessible kernel virtual address candidate
static inline uint64_t probe(void *addr) {
    uint64_t t0, t1;
    asm volatile("mfence");
    t0 = __rdtscp(&aux);
    __builtin_prefetch(addr, 0, 0);   // prefetchnta — never faults
    t1 = __rdtscp(&aux);
    asm volatile("mfence");
    return t1 - t0;                    // cycles the prefetch itself took
}

rdtscp kısmen serializing'tir; prefetch'in translation işi ölçülen pencerenin içine düşsün diye onu mfence/lfence ile eşleyin. Address başına çok sayıda sample'ın ortalamasını alın ve gürültüyü bastırmak için minimum'u alın.

2. KASLR base adaylarını tara. Kernel image base'i küçük bir 2 MB hizalı slot kümesi üzerinde randomize edilir:

for (uint64_t base = KERNEL_LOW; base < KERNEL_HIGH; base += STEP) {
    uint64_t min = ~0ULL;
    for (int i = 0; i < TRIES; i++) {
        uint64_t c = probe((void*)base);
        if (c < min) min = c;
    }
    record(base, min);   // mapped base => systematically lower minimum
}

Map'li (gerçek) base, map'siz tahminlere göre daha hızlı prefetch olur çünkü translation paging-structure cache'lerinde/TLB'de mevcuttur; aykırı (outlier) base sızdırılan KASLR offset'idir.

3. ret2dir / direct-map çözümlemesi (address-translation oracle). Bilinen bir user physical page'in direct-map alias'ını prefetch etmek ve ardından user mapping'in timing'ini ölçmek virtual→physical ilişkisini çözer; direct-physical map'in nerede yaşadığını açığa çıkarır — makalenin SMAP'i bypass etmek ve ret2dir'i mümkün kılmak için kullandığı yapı taşı.

Bu bir timing oracle, leak primitive değil

Prefetch ayrıcalıklı veriyi bir register'a okumaz. Yalnızca sonradan timing'ini ölçtüğünüz microarchitectural state'i (cache/TLB doluluğu) değiştirir. Sinyal küçüktür (onlarca cycle) ve CPU/microcode'a bağlıdır; sonraki birçok parçada bu fark azalmış ya da yok olmuştur.

Detection

Yazılımdan tespiti zor: saldırı, syscall ve fault olmayan sıkı bir ayrıcalıksız prefetch/rdtsc loop'udur. Anormal rdtsc/rdtscp oranları ya da TLB-miss pattern'leri için performance-counter izlemesi olağan yaklaşımdır, ama gürültülüdür. Ayrıcalıksız rdtsc'yi devre dışı bırakmak (CR4.TSD) en ucuz timer'ı kaldırır ama daha kaba timing kaynakları kalır.

Mitigation

(Artık risk / bypass.) KPTI / KVA shadow çoğu kernel mapping'ini user page table'larından kaldırır, böylece kernel address'lerinin user-mode prefetch'i translate edecek bir şey bulamaz — klasik varyantı kapatır. EntryBleed saldırısı, user page table'larında map'li kalmak zorunda olan birkaç address'i (syscall entry trampoline'i) prefetch ederek bunu KPTI'a karşı diriltir ve kernel text base'ini yeniden türetir. Daha güçlü entropy (KASLR, FG-KASLR) tarama maliyetini yükseltir ama oracle'ı kaldırmaz. Ayrıca bkz. prefetch-timing-kaslr-bypass ve bağımsız prefetch-side-channel.

References