Skip to content

Spectre

Bir victim'i, architecturally çalıştırmayacağı instruction'ları transiently yürütmeye yönlendir, secret'ı microarchitectural state'e encode et ve onu bir covert channel üzerinden kurtar.

Mechanism

Note

Modern CPU'lar speculate eder. Branch-resolution ve bellek latency'sini gizlemek için branch'lerin sonucunu (yön ve target) öngörür ve ileri koşar; instruction'ları transiently — program sırasının dışında ve kontrol eden koşul bilinmeden önce — yürütür. Tahmin yanlışsa CPU architectural sonuçları (register'lar, flag'ler, bellek) atar ve doğru path'e yeniden yönlenir. Spectre'nin suistimal ettiği invariant: rollback yalnızca architectural'dır. Transiently yürütülen instruction'lar yine de squash'tan sağ çıkan microarchitectural yan etkiler — en ünlüsü cache'e çekilen bir line — bırakır.

Kocher et al. saldırıyı, "a victim to speculatively perform operations that would not occur during correct execution" yönlendirmek ve confidential bilgiyi "via a side channel to the adversary" sızdırmak olarak tanımlar. Bu yüzden attacker (1) bir predictor'ı eğitir/poison'lar ki victim seçilen bir path'e mis-speculate etsin, (2) transient path'in secret-dependent bir bellek erişimi yapmasını ayarlar ve (3) secret'ı microarchitectural footprint'ten FLUSH+RELOAD gibi bir covert channel üzerinden kurtarır. Meltdown'un aksine Spectre bir faulting instruction'a dayanmaz — victim'in kendi kodunun doğru speculation'ını suistimal eder.

Walkthrough

Kocher et al.'den kanonik disclosure gadget'ı (Spectre Variant 1, PHT/bounds-check bypass):

// array1_size, array1, array2 are in the victim. x is attacker-influenced.
if (x < array1_size) {
    y = array2[array1[x] * 4096];   // transiently runs for out-of-bounds x
}
  1. Predictor'ı eğit. Gadget'ı in-bounds x ile tekrar tekrar çağır ki branch predictor bounds check'in "taken" (true) olduğunu öğrensin.

  2. Mistrain + tetikle. Out-of-bounds bir x ver. Hâlâ "true" öngören CPU, gövdeyi transiently yürütür: secret byte array1[x]'i okur, onu distinct cache line'lara yaymak için page boyutuyla (4096) çarpar ve array2'yi indexlemek için kullanır. Bu load, array2'nin secret-dependent bir line'ını cache'e getirir.

  3. Covert channel ile kurtar. Misspeculation squash edildikten sonra, array2 boyunca erişimleri zamanla (FLUSH+RELOAD). Tek hızlı (cache'lenmiş) line secret byte'ı ortaya koyar.

flush(array2);                 // evict all probe lines
victim_function(malicious_x);  // transient secret-dependent load happens here
for (i = 0; i < 256; i++)      // reload-and-time each candidate line
    if (reload_time(&array2[i * 4096]) < THRESHOLD)
        recovered = i;         // cached line == leaked byte value
Spectre ailesinin kavramsal yapısı

Spectre-PHT  (Variant 1)  Pattern History Table   -> mispredict branch DIRECTION
Spectre-BTB  (Variant 2)  Branch Target Buffer    -> mispredict branch TARGET
Spectre-RSB               Return Stack Buffer      -> mispredict RETURN target
Spectre-STL  (Variant 4)  store-to-load forwarding -> speculative stale load
Tüm varyantlar arasındaki ortak invariant: bir microarchitectural predictor yönlendirilir, bir transient secret-dependent erişim gerçekleşir ve bir covert channel sonucu exfiltrate eder. Varyantlar yalnızca hangi predictor'ın suistimal edildiğinde farklılaşır.

Detection

Temiz bir architectural iz yoktur — tasarımı gereği transient path geri alınır. Hardware performance counter'ları (branch misprediction'ları, cache miss'leri) gürültülü vekillerdir ve kolayca atlatılır; pratik savunma detective değil, preventive'dir.

Mitigation

Mitigation'lar varyant başınadır ve software ile hardware/microcode'u birleştirir: serialize eden barrier'lar (lfence), PHT için Speculative Load Hardening / branchless bounds masking ve BTB için indirect-branch kontrolleri (retpoline, IBRS/eIBRS, IBPB, STIBP). Indirect-branch'e özel savunmalar için BTB notlarına bak. Canella et al.'ye göre, deploy edilmiş tek bir savunma her varyantı kapsamaz.

Ayrıca bkz.: Spectre-BTB, FLUSH+RELOAD, PRIME+PROBE.

References