Skip to content

Retbleed return thunk (jmp2ret)

Retbleed mitigation: replace every ret with a jmp to a single return thunk that first untrains the branch predictor (UNTRAIN_RET / zen_untrain_ret), so speculative return-target injection (Retbleed, CVE-2022-29900 / CVE-2022-29901) can no longer steer returns to a gadget.

Mechanism

Neden çalışır

Retbleed, retpoline'ın temel varsayımının — ret'in yalnızca güvenli Return Stack Buffer'dan predict edildiği — etkilenen core'larda yanlış olduğunu gösterdi. AMD Zen 1/1+/2'de ret predictor'ı BTB üzerinden eğitilebilir; belirli Intel core'larında (6.–8. Nesil) genel bir indirect predictor return'leri yanlış predict edebilir. O predictor'ı zehirleyen bir saldırgan, bir victim ret'inin spekülatif olarak seçilmiş bir gadget'a atlamasını sağlayabilir — tam olarak Spectre v2 primitive'i, ama return'ler üzerinden.

Düzeltme, eğitilebilir davranışı kaldırır. Her ret, jmp __x86_return_thunk'a yeniden yazılır. Thunk, UNTRAIN_RET üzerinden yönlendirilir; bu, kötü amaçlı predictor state'ini evict eden / overwrite eden microarchitecture'a özgü bir dizi (AMD'de zen_untrain_ret) çıkarır, böylece sonraki "safe return" saldırganın gadget'ı yerine bilinen-iyi-huylu bir konuma predict edilir. Invariant: herhangi bir return commit olmadan önce, bir saldırganın zehirleyebileceği predictor entry'si yok edilmiştir, spekülasyon penceresini çökertir.

Walkthrough

1. Return'ler bir thunk'a jump olur. Mitigation derlemeye dahil edildiğinde (-mfunction-return=thunk-extern), compiler çıplak bir ret üretmez; kernel'in patch edebileceği kernel'in return thunk'ına bir jump üretir:

   ...                        ; function body
   jmp __x86_return_thunk     ; instead of `ret`  (this is the "jmp2ret" path)

Thunk, UNTRAIN_RET ve ardından kontrollü bir "safe return" (AMD'de zen_untrain_ret / srso_safe_ret) yapar; mimari return çözülmeden önce predictor'ı bilinen bir yola zorlar.

2. Boot'ta mitigation yöntemini seç. Kernel retbleed='i sunar:

retbleed=off            # no mitigation
retbleed=auto           # pick based on CPU (default)
retbleed=unret          # force untrained return thunks; effective on AMD f15h-f17h
retbleed=ibpb           # use IBPB instead (flush predictor on entry)
retbleed=unret,nosmt    # also disable SMT where the mitigation needs it

unret, yukarıda anlatılan return-thunk yoludur; yalnızca AMD Zen 1/2 ailesi parçalarda etkilidir. Intel parçalar genellikle IBRS / RSB stuffing / diğer yollara dayanır.

3. Neyin aktif olduğunu doğrula.

$ cat /sys/devices/system/cpu/vulnerabilities/retbleed
Mitigation: untrained return thunk; SMT disabled
# or, on Intel:
Mitigation: IBRS

Pahalı

Kernel maintainer'ları Retbleed patch'lerinden %14–%39 overhead ölçtü (AMD daha düşük, Intel daha yüksek). Maliyet nedeniyle, her return'de untrain etmek yerine RSB'nin underflow etmesini engellemek için daha düşük overhead'li bir alternatif — call depth tracking — geliştirildi.

Detection

Mitigation, yukarıdaki sysfs vulnerabilities dosyası aracılığıyla gözlemlenebilir. Return thunk ile build edilmiş bir kernel, patch edilmiş fonksiyonların disassembly'sinde ret yerine jmp __x86_return_thunk gösterir; dmesg boot'ta seçilen yöntemi bildirir (örn. Spectre V2 : ... return thunk).

Mitigation

(Artık risk / bypass.) Untraining microarchitecture'a özgüdür; return prediction'ı unret dizisi tarafından kapsanmayan bir core IBPB'ye geri döner ya da açık kalır. Zen'deki yakından ilişkili SRSO / Inception saldırısı, return-stack overflow'unun kendi thunk'ına (srso_safe_ret) ihtiyacı olduğunu gösterdi ve call-depth tracking, untraining gücünün bir kısmını performans için takas eder.

References