我正在读this article关于与Spectre类似的理论CPU漏洞,它指出:
“攻击者需要训练分支预测器,使其 可靠地预测了分支。”
我大致了解什么是分支预测及其工作原理,但是“训练”分支预测器意味着什么?这是否意味着要偏重一个分支,使其在计算上比另一个分支昂贵得多,还是在循环之前让CPU继续正确地预测某个特定分支,然后继续进行错误预测的下一个分支?
例如
// Train branch predictor
for (int i = 0; i < 512; i++)
{
if (true){
// Do some instructions
} else {
// Do some other instruction
}
}
// The branch predictor is now "trained"/biased to predict the first branch?
// Proceed to attack
分支预测器是否基于先前的预测/错误预测使用权重对预测进行偏向或偏向?
答案 0 :(得分:4)
这意味着创建一个分支来别名您要攻击的分支(通过将其置于特定地址,也许与另一个进程中的虚拟地址相同,或者使用4k或其他2偏移量的幂可能起作用),并运行很多次以使预测变量有偏差。
这样一来,当您使用Spectre攻击的分支实际运行时,就会按照您希望的方式进行预测。 (或者对于间接分支,将跳转到所需的虚拟地址。)
基于分支历史(动态指令流中通往该分支的其他分支)的现代TAGE分支预测变量索引,因此适当的训练可能会变得很复杂...
但是,在最简单的层次上,是的,状态多于1位的分支预测器记住的不仅仅是最后一个分支方向。 Wikipedia has a big article,涉及分支预测的许多不同实现,从简单的2级饱和计数器开始。
训练它们涉及使您控制的分支重复相同的方式。
具体来说,您会将这样的asm放入循环中(在已知地址处),然后重复运行。
xor eax,eax ; eax=0 and thus set ZF
jnz .target ; always not-taken
然后,即使正常情况下,目标分支也将通过并运行您想要的Spectre“小工具”。
答案 1 :(得分:1)
分支预测器通过记住最近的分支目标来工作。最简单的预测形式只是记住上一次被击中是哪个分支。存在更复杂的预测变量并且很常见。
“培训”只是填充该内存。对于简单的(一值)预测变量,这意味着一次选择您希望使用的分支。对于复杂的预测器,这将意味着多次执行优先分支,直到处理器可靠地预测出所需的结果为止。