2

几年前,我用下面的这个宏编写并更新了我们的 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
 

反汇编显示了推测指令是如何插入的

幽灵v2

问题

在 2021 年,我是否可以安全地删除该 MASM 宏并依靠 CPU 微码更新等……来解决任何 Spectre 问题?对于 C 代码,看起来 M$ 和 Linux C 编译器已经解决了它:

  • Microsoft在其 MSVC 编译器中添加了/Qspectre 。
  • GCC 具有通过 -mfunction-return 等减轻 Spectre v2 的编译器选项,...

谢谢。

4

1 回答 1

2

这些编译器选项通过生成特殊的 asm 来工作,无论是 retpolineslfence还是其他。当您手动编写 asm 时,显然是否手动包含特殊 asm 仍然取决于您。

对操作系统的更改与您相关。在具有更新微码的 CPU 上的操作系统可以通过告诉 CPU 不允许过去代码的分支历史影响未来代码来保护您免受其他线程的影响。(要求它这样做的能力是在微码更新中添加的,通常只需刷新分支预测缓存即可)。

在同一物理内核的另一个逻辑内核上执行的另一个软件线程可以在大多数 CPU 上“攻击”您的代码,因为分支预测器是共享的。至少在理论上;如果两个任务都需要为它们的分支目标使用相同的虚拟地址来启动预测器,那么 ASLR 可能会使这种情况变得不可信。

因此,在用户空间中,我认为如果您担心代码在同一线程中运行(例如,在浏览器中运行不受信任的代码的 JIT 引擎或 JVM 必须保护自己)或在同一线程中运行,我认为您只需要保护自己免受 Spectre 的攻击物理核心。

于 2021-10-08T07:19:25.577 回答