跨執行緒返回地址預測¶
某些 AMD 和海光處理器存在跨執行緒返回地址預測漏洞。在 SMT 模式下執行時,當一個同級執行緒從 C0 狀態轉換出去時,另一個同級執行緒可能會使用從 C0 狀態轉換出去的同級執行緒的返回目標預測。
Spectre v2 緩解措施保護 Linux 核心,因為它在上下文切換到空閒執行緒時,會用安全的目標填充返回地址預測條目。然而,KVM 允許 VMM 在從 C0 狀態轉換出去時阻止退出客戶機模式。這可能導致由客戶機控制的返回目標被同級執行緒使用。
受影響的處理器¶
以下 CPU 存在漏洞
AMD Family 17h 處理器
海光 Family 18h 處理器
問題¶
當 SMT 啟用時,受影響的支援 SMT 的處理器支援 1T 和 2T 執行模式。在 2T 模式下,核心中的兩個執行緒都在執行程式碼。要使處理器核心進入 1T 模式,需要其中一個執行緒請求從 C0 狀態轉換出去。這可以透過 HLT 指令或請求非 C0 的 MWAIT 指令來傳達。當執行緒重新進入 C0 狀態時,處理器會轉換回 2T 模式,前提是另一個執行緒也仍在 C0 狀態下。
在受影響的處理器中,返回地址預測器 (RAP) 根據 SMT 模式進行分割槽。例如,在 2T 模式下,每個執行緒使用一個私有的 16 條目 RAP,但在 1T 模式下,活動執行緒使用一個 32 條目 RAP。在 1T/2T 模式之間轉換時,RAP 內容不會被修改,但 RAP 指標(控制用於預測的下一個返回目標)可能會改變。這種行為可能導致在 1T/2T 切換後,一個 SMT 執行緒的返回目標被同級執行緒的 RET 預測使用。特別是,在轉換為 1T 後立即執行的 RET 指令可能使用剛進入空閒狀態的執行緒的返回目標。理論上,如果使用的返回目標不是來自可信程式碼,這可能導致資訊洩露。
攻擊場景¶
可以透過在受影響的處理器上執行一系列具有目標返回位置的 CALL 指令,然後轉換出 C0 狀態來發起攻擊。
緩解機制¶
在進入空閒狀態之前,核心會將上下文切換到空閒執行緒。上下文切換透過執行一系列 CALL 指令,用安全的目標填充 RAP 條目(在 Linux 中稱為 RSB)。
透過攔截 HLT 和 MWAIT 指令,阻止客戶機虛擬機器直接使處理器進入空閒狀態。
完全解決此問題需要以上兩種緩解措施。
核心命令列上的緩解控制¶
使用現有的 Spectre v2 緩解措施,這些措施將在上下文切換時填充 RSB。
KVM 緩解控制 - 模組引數¶
預設情況下,KVM 虛擬機器監控程式透過攔截客戶機嘗試從 C0 轉換出去來緩解此問題。VMM 可以使用 KVM_CAP_X86_DISABLE_EXITS 功能來覆蓋這些攔截,但由於這不常見,因此覆蓋此路徑的緩解措施預設未啟用。
KVM_CAP_X86_DISABLE_EXITS 功能的緩解措施可以透過布林模組引數 mitigate_smt_rsb 啟用,例如 kvm.mitigate_smt_rsb=1。