Prefetch Side Channel (kernel ASLR break)¶
x86 software
prefetchinstruction'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
prefetchartırdtscpissue 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.