幾年前,我使用下面的這個宏撰寫并更新了我們的 MASM 代碼庫,以對抗 Spectre V2。
NOSPEC_JMP MACRO target:REQ
PUSH target
JMP x86_indirect_thunk
ENDM
NOSPEC_CALL MACRO target:REQ
LOCAL nospec_call_start
LOCAL nospec_call_end
JMP nospec_call_end
ALIGN 16
nospec_call_start:
PUSH target
JMP x86_indirect_thunk
ALIGN 16
nospec_call_end:
CALL nospec_call_start
ENDM
.CODE
;; This is a special sequence that prevents the CPU speculating for indirect calls.
ALIGN 16
x86_indirect_thunk:
CALL retpoline_call_target
;; No benefit from aligning the capture_speculation branch target, as it is only potentially speculatively executed.
capture_speculation:
PAUSE
JMP capture_speculation
ALIGN 16
retpoline_call_target:
IFDEF WIN64
LEA RSP,[RSP 8]
ELSE
LEA ESP,[ESP 4]
ENDIF
RET
例如,這里有一些啟用了推測的匯編代碼 (MST_QSPECTRE=1)
main PROC NEAR C
PUSH ESI
PUSH EDI
PUSH EBX
PUSH EBP
MOV EAX,OFFSET MyFun
;; Generated code to Call an indirect pointer without speculation.
IFDEF MST_QSPECTRE
NOSPEC_CALL EAX
ELSE
CALL EAX
ENDIF
POP EBP
POP EBX
POP EDI
POP ESI
RET
main ENDP
反匯編顯示了如何插入推測性指令

題
在 2021 年,我可以安全地洗掉該 MASM 宏并依靠 CPU 微代碼更新等來解決任何 Spectre 問題嗎?對于 C 代碼,看起來 M$ 和 Linux C 編譯器已經解決了它:
- 微軟在他們的 MSVC 編譯器中添加了/Qspectre。
- GCC 具有通過 -mfunction-return 等方式緩解 Spectre v2 的編譯器選項,...
謝謝。
uj5u.com熱心網友回復:
這些編譯器選項通過生成特殊的 asm 來作業,無論是 retpolineslfence還是其他任何東西。當您手動撰寫 asm 時,顯然是否手動包含特殊 asm 仍然取決于您。
對作業系統的更改與您息息相關。在具有更新微代碼的 CPU 上,作業系統可以通過告訴 CPU 不允許來自過去代碼的分支歷史影響未來代碼來保護您免受其他執行緒的侵害。(要求它這樣做的能力是在微碼更新中添加的,通常只需重繪 分支預測快取即可)。
在同一物理內核的另一個邏輯內核上執行的另一個軟體執行緒可以“攻擊”您在大多數 CPU 上的代碼,因為分支預測器是共享的。至少在理論上;如果兩個任務都需要為其分支目標使用相同的虛擬地址來準備預測器,那么 ASLR 可能會使這變得難以置信。
因此,在用戶空間中,如果您擔心在同一執行緒中運行的代碼(例如,在瀏覽器中運行不受信任的代碼的 JIT 引擎或 JVM 必須保護自己)或在同一執行緒上,我認為您只需要保護自己免受 Spectre 的攻擊物理核心。
轉載請註明出處,本文鏈接:https://www.uj5u.com/qianduan/313722.html
下一篇:符號表中的值是什么?
