Prime+Probe¶
Bir
cache set'ini kendi line'larınla doldur, victim'in çalışmasına izin ver, sonra set'e tekrar eriş ("probe") ve süresini ölç — bir yavaşlama victim'in line'larından birini evict ettiği, yani o set'e dokunduğu anlamına gelir. Shared memory gerektirmez.
Mechanism¶
Neden çalışır
Bir set-associative cache her adresi tam olarak W way'den oluşan bir
set'e map'ler. Set aynı anda en fazla W line tutabilir; aynı set'e
map'lenen W+1'inci bir line getirmek bir eviction'a zorlar. Prime+Probe
bu capacity conflict'ini bir ölçüme dönüştürür.
Attacker önce bir eviction set kurar: hepsi aynı target set'e map'lenen
W adetlik bir adres grubu (congruent adresler). Invariant şu:
eğer attacker bir set'i tamamen dolduruyorsa, o set'e sonradan yaptığı her
erişim hızlıdır — ama arada victim aynı set'e dokunduysa hariç, o durumda
bir attacker line'ı evict edilmiştir ve o erişim artık yavaştır. Re-access'i
ölçmek bu yüzden victim ile herhangi bir memory paylaşmadan victim'in set'e
erişip erişmediğini ortaya çıkarır.
Flush+Reload'un aksine Prime+Probe shared page ve clflush gerektirmez.
Yalnızca cache capacity için contention'a dayanır, dolayısıyla security
boundary'leri aşar (cross-VM, cross-process). Intel CPU'larda last-level cache
(LLC) tarihsel olarak inclusive olmuştur: bir line'ı LLC'den evict etmek onu
her core'un private L1/L2'sinden de evict eder, yani bir core'daki attacker LLC
contention'ını kullanarak başka bir core'da çalışan bir victim'i gözetleyebilir.
Bu, Liu, Yarom, Ge, Heiser ve Lee'nin (IEEE S&P 2015) pratik cross-core,
cross-VM saldırısının temelidir; bu saldırı VM'ler arasında bir GnuPG El Gamal
key'ini geri çıkarır. Orijinal cache-set contention fikri Osvik, Shamir ve
Tromer'e (CT-RSA 2006) aittir; onlar bunu L1 cache'teki AES T-table'larına karşı
kullanmıştır.
Walkthrough¶
İki primitive var: doğru bir timer (rdtscp) ve target set için congruent bir
eviction set.
// gcc -O2 primeprobe.c -o pp (x86-64)
#include <stdint.h>
#include <x86intrin.h> // __rdtscp
// es[0..W-1] : W addresses that all map to the SAME cache set
void *es[W];
static inline void prime(void) {
for (int i = 0; i < W; i++) // fill the target set with our lines
(void)*(volatile char *)es[i];
}
static inline uint64_t probe(void) {
unsigned aux;
uint64_t t0 = __rdtscp(&aux);
for (int i = 0; i < W; i++) // re-access every line, timed
(void)*(volatile char *)es[i];
uint64_t t1 = __rdtscp(&aux);
return t1 - t0; // slow => a line was evicted
}
Saldırı döngüsü prime → bekle → probe şeklindedir:
for (;;) {
prime(); // occupy the whole set
nanosleep(&slot, NULL); // give the victim a slot to run
uint64_t t = probe(); // time the re-access
record(t); // t high => victim used this set
}
Eviction set'i kurmak kritik adımdır. 2 MB'lık huge page'lerle düşük 21
adres biti attacker-controlled olur, bu da cache-set index bitlerini sabitler ve
(bilinen bir makinede) congruent adresleri sayıp çıkarmanı sağlar; aksi halde
onları dinamik olarak keşfedersin (bkz. cache-eviction-set-construction).
Kalibrasyondan sonra primed (her şey cache'te) ve contended re-access süreleri
temiz biçimde ayrışır:
$ ./pp --calibrate
probe, no victim activity : ~120 cycles (all W lines still cached)
probe, victim touched set : ~330 cycles (>=1 line evicted -> DRAM refill)
threshold chosen : ~220 cycles
Zaman içinde set başına aktivite trace'i (collapsed)
Birçok set'i paralel olarak izlemek victim'in secret-dependent access pattern'ini yeniden kurar (örn. hangi table/exponentiation line'larına dokunduğunu).
Bu not vs. JavaScript Prime+Probe
Bu not, native kod (rdtscp, huge page'lerle congruent adresler) varsayan
genel Prime+Probe primitive'idir — cross-VM/cross-process LLC contention'a
odaklanır. Aynı primitive'in clflush/native-timer/physical-adres olmadan,
sandbox'lı bir browser içinden çalıştırılan varyantı için bkz.
JavaScript Prime+Probe (timer reconstruction +
COOP/COEP mitigation'ları orada).
Non-inclusive cache'ler
Daha yeni Intel server CPU'ları (Skylake-SP ve sonrası) non-inclusive bir LLC kullanır, dolayısıyla düz LLC Prime+Probe artık victim'in private erişimlerini şeffaf biçimde göremez. Devam çalışmaları bunun yerine directory/snoop filter'ı hedef alır, Prime+Scope ise high-precision varyantı geliştirir.
Detection¶
- HPC monitoring: yükselen
LLC-load-misses/cache-missesve sabit bir congruent adres set'i üzerinde tekrarlayan yürüyüşler davranışsal bir imzadır (perf stat -e LLC-load-misses,cache-misses). - Faydalı iş yapmayan sıkı
rdtscp+ eviction-set-walk döngüleri Flush+Reload imzasına benzer, amaclflusholmadan.
Mitigation¶
- Constant-time code: secret-dependent memory adresi olmaması, böylece erişilen cache set'lerinin kümesi secret'tan bağımsız olur.
- Cache partitioning / coloring (örn. Intel CAT) ile attacker'a victim'le paylaşılan, contended bir set vermemek.
- Randomized cache'ler (ScatterCache, CEASER/CEASER-S) sabit address→set mapping'ini kırar, böylece eviction set kurmak zorlaşır — gerçi Prime+Prune+Probe bunlara hâlâ saldırır.
References¶
- Fangfei Liu, Yuval Yarom, Qian Ge, Gernot Heiser, Ruby B. Lee. Last-Level Cache Side-Channel Attacks are Practical. IEEE S&P 2015 — https://dl.acm.org/doi/10.1109/SP.2015.43
- Dag Arne Osvik, Adi Shamir, Eran Tromer. Cache Attacks and Countermeasures: the Case of AES. CT-RSA 2006 — https://eprint.iacr.org/2005/271