Skip to content

Prefetch Side Channel (kernel ASLR break)

x86 software prefetch instruction'larının timing'ini ve davranışını suistimal ederek bir kernel virtual address'inin map'li olup olmadığını öğrenmek ve virtual-to-physical translation'ları çözmek; böylece KASLR ve SMAP'i devre dışı bırakmak.

Mechanism

Note

x86 prefetch instruction'ları (prefetcht0, prefetchnta, vb.) advisory'dir: software'e görünür exception'lar ve permission check'ler büyük ölçüde bastırılır, ancak instruction yine de page table'ları walk eder ve execution time'ı operand address'in translation state'ine bağlıdır. TLB / paging hierarchy içinde present olan bir address'i prefetch etmek, walk edilmesi gereken ya da unmapped olan bir address'i prefetch etmekten daha hızlıdır. Attacker, user space'ten candidate kernel address'leri üzerinde prefetch timing'ini ölçerek hangi address'lerin map'li olduğunu çıkarır — ve timing'leri korele ederek paging hierarchy'yi yeniden kurabilir ve bir virtual address'i physical address'ine çözebilir.

Gruss, Maurice, Fogh, Lipp, Mangard ("Prefetch Side-Channel Attacks: Bypassing SMAP and Kernel ASLR", CCS 2016) iki saldırı sunar: bir process'in tüm paging hierarchy'sini geri kazanan (user ve kernel ASLR'yi kıran) bir translation-level oracle ve virtual'dan physical'a address'leri çözerek SMAP'i bypass eden bir address-translation oracle. prefetch, access permission'lardan bağımsız olarak translation bilgisini sızdırdığından, temel bir KASLR-break primitive'i hâline geldi ve sonraki saldırıların (örn. EntryBleed-style entry-trampoline leak'leri) bir bileşeni oldu.

Walkthrough

Temel ölçüm: bir candidate address üzerinde prefetch'i zamanla; cache'lenmiş/map'li translation'lar daha hızlı çözülür.

static inline uint64_t time_prefetch(void *addr) {
    uint64_t t0, t1;
    asm volatile("mfence; rdtscp" : "=a"(t0) :: "rcx","rdx","memory");
    __builtin_prefetch(addr, 0, 3);     // prefetcht0; no fault even for kernel addr
    asm volatile("rdtscp" : "=a"(t1) :: "rcx","rdx","memory");
    return t1 - t0;
}

Candidate kernel base address'leri tarayınca gerçek olanı bir timing outlier olarak ortaya çıkar:

for base in KASLR_candidate_bases:
    prime translation state (flush/evict as needed)
    t = min over repeats of time_prefetch(base + known_offset)
    record (base, t)
# The correctly-mapped kernel base shows a systematically different (faster)
# prefetch latency -> KASLR defeated; repeat to resolve V->P for SMAP bypass.

Detection

  • Kernel-range address'ler üzerinde prefetch artı rdtscp issue eden tight loop'lar alışılmadık bir pattern'dır; TLB activity'sinin performance-counter ile izlenmesi bunu işaretleyebilir, ancak channel'ın kendisi architectural bir fault bırakmaz.

Mitigation

  • KPTI / KAISER (kernel page-table isolation) kernel'in çoğunu user page table'larından unmap eder, böylece prefetch oracle'ı translation target'larından mahrum bırakır.
  • Daha güçlü KASLR entropy'si ve user-accessible high-resolution timer'ları kaldırmak maliyeti yükseltir.

References