Spectre-STL (Variant 4, CVE-2018-3639)¶
Speculative Store Bypass: memory-disambiguation predictor, bir load'un daha eski, address'i resolve edilmemiş bir store'u speculative olarak atlamasına ve stale (bayat) bir değer forward etmesine izin verir; store'un üzerine yazmak üzere olduğu data'nın transient bir read'ini açar.
Mechanism¶
Note
Instruction-level parallelism çıkarmak için, bir CPU bir load'un address'i hâlâ hesaplanan her eski store'u beklemesini istemez. Memory disambiguation predictor, bir load'un herhangi bir in-flight store'la alias'layıp (örtüşüp) örtüşmediğini tahmin eder. "Alias yok" predict ederse, load speculative olarak memory'ye karşı execute olur ve o bekleyen store'dan store-to-load forwarding'i bypass eder — konumdaki, store'un yazacağı değer yerine eski (stale) değeri okur. Store address'i nihayet resolve olduğunda ve prediction yanlışsa, pipeline architectural sonucu geri sarar, ama transient load sonraki speculative instruction'ları yönlendirmek için stale değeri zaten kullanmıştır. Kırılan invariant: software, bir load'dan mantıksal olarak önce gelen bir store'un o load tarafından gözlemlendiğini varsayar. Misprediction altında load transient olarak pre-store memory'yi görür ve dependent bir access o değeri bir microarchitectural side channel'a encode eder. Bu bir Spectre-class bug'dır (misprediction'dan kaynaklanan transient window), ama suistimal edilen predictor bir branch predictor değil, store/load disambiguation'dır — dolayısıyla branch-targeted savunmalar (retpoline, IBRS) bunu ele almaz.
Walkthrough¶
Kavramsal olarak bu, bir branch mispredict yerine bir store/load mispredict tarafından sürülen bir spectre tarzı read primitive'idir.
- Örtüşen store-sonra-load düzenle. Bir slot'a bir değer yaz, sonra aynı slot'u resolve olması daha yavaş bir address hesabıyla oku, böylece disambiguation predictor load'u erken bırakmaya teşvik edilir.
Kavramsal parça
-
Predictor'ı mistrain et ki load için aliasing yok predict etsin ve az önce store edilmiş değeri değil, stale değeri forward etsin.
-
Transient encode. Dependent access (
array[stale * stride]), stale secret'a dayalı olarak attacker'ın seçtiği bir cache line'ı getirir. -
flush-reload ya da prime-probe ile recover et.
Warning
Pratik risk en güçlü olarak, attacker kodunun ve security check'lerinin bir address space'i paylaştığı language sandbox'ları / JIT'lerin (örn. JavaScript engine'leri) içindedir: bir değeri yeniden initialize eden ya da bounds-mask'leyen bir store transient olarak bypass edilebilir ve check'in nötralize etmesi gereken data'yı açığa çıkarır.
Detection¶
Architectural iz yok. Variant 4 belirgin bir host log'u ya da EDR event'i
üretmez; misprediction ve rollback software'e görünmezdir. İzlenen bir core'da
memory-ordering machine clear'larının (MACHINE_CLEARS.MEMORY_ORDERING) kaba
perf-counter izlenmesi yoğun disambiguation çalkalanmasına işaret edebilir, ama
güvenilir bir detector değildir. Savunma preventive'dir.
Mitigation¶
- Speculative Store Bypass Disable (SSBD): microcode, IA32_SPEC_CTRL MSR
(SSBD bit) üzerinden, set edildiğinde load'un eski store'ları bypass etmesini
önleyen bir kontrol açar. OS'e
spec_store_bypass_disableolarak açılır (speculative-store-bypass-disable). - SSBD performansa mal olduğu için, OS'ler bunu genellikle global yerine seçici
uygular (örn. process başına
prctl/seccomparacılığıyla); değerlendirilen risk göz önüne alındığında birçok sistemde varsayılan olarak kapalı bırakılır. - AMD eşdeğer bir SSBD kontrolü sağlar; etkilenen Arm core'ları per-architecture kontroller açar.
- CPU microcode/firmware ve OS mitigation paketlerini güncel tut.