Spectre(与 Metldown 不同)得益于 CPU 处理分支预测的方式。从您所指的同一篇论文中
[2.3] 推测执行要求处理器对分支指令的可能结果进行猜测。更好的预测通过增加可以成功提交的推测执行操作的数量来提高性能。
(...)
为了预测是否采用条件分支,处理器会保留最近分支结果的记录。
然后
x
[4] 代码片段以对安全性至关重要的边界检查开始。特别是,此检查可防止处理器读取array1
. 否则,越界输入x
可能会触发异常或可能导致处理器通过提供x = (address of a secret byte to read)−(base address of array1)
.
但是这篇论文继续解释了为什么这可能会起作用,而不是触发异常:
不幸的是,在推测执行期间,边界检查的条件分支可能会遵循不正确的路径。例如,假设一个对手导致代码运行如下:
• 的值x
被恶意选择(并且越界),从而array1[x]
解析为受害者内存中某处的秘密字节k ;
• array1
size 并且array2
不存在于处理器的缓存中,但k被缓存;和
• 先前的操作接收到的值x
是有效的,导致分支预测器假设if 可能为真。
最后,CPU,在x
值被评估为过高后,将有效地绕过if
主体,不会撤销检索到的y
值。但是缓存状态发生了变化,这就是攻击发生的地方:
处理器意识到其推测执行是错误的,并回退其寄存器状态。但是,在实际处理器上,推测性读取array2
以特定于地址的方式影响缓存状态,其中地址取决于k
未经授权的访问array1[x]
是在推测代码执行期间进行的,因此不会引发异常,因为 CPU“知道”如果之前分支的条件恰好为假,那么推测执行的结果将不会退出。
(与 Meltdown 不同,它会在执行的用户代码确实访问未经授权的区域时触发异常 - Meltdown 利用退出异常所花费的时间与在该访问之后预先执行的少数无序指令之间的竞争条件(以及不会退休))。