跨執行緒返回地址預測

某些 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