在计算机体系结构中,分支预测器(Branch predictor)是一种数字电路,在分支指令执行结束之前猜测哪一路分支将会被运行,以提高处理器的指令流水线的性能。使用分支预测器的目的,在于改善指令管线化的流程,进而通过指令管线化提高处理器性能,分支预测器是现今指令流水线微处理器性能提升的关键技术之一。
01 分支类型
按照是否条件执行以及是否直接寻址可以将分支分为下表中的四类:
分类方式 | 条件执行 | 非条件执行 |
直接寻址 | 条件分支 | 立即分支 |
间接寻址 | 无 | 返回分支 间接分支 |
按照分支指令是否需要满足某条件后才会发生分支跳转,将指令执行方式分为条件执行和非条件执行。
按照指令寻址模式(直接寻址和间接寻址)的不同,分为直接寻址分支和间接寻址分支。直接寻址分支的跳转偏移量被编在指令码中,可直接由指令码计算得出跳转地址,间接寻址分支的跳转地进位于寄存器中,随寄存器值的变化而改变。
02 分支预测技术
分支预测技术根据使用目的不同,可分为两类:条件分支跳转方向的预测和分支目标地址的预测。这两种分支预测目的结合四种不同分支指令类型,形成不同的分支预测技术,下表中列出了具体的分支预测技术类型:
序号 | 分支类别 | 跳转方向预测 | 目标地址预测 |
1 | 条件分支 | 条件分支跳转方向预测技术 | 分支目标地址预测技术 |
2 | 立即分支 | 无相关技术 | 分支目标地址预测技术 |
3 | 返回分支 | 无相关技术 | 返回地址预测技术 |
4 | 间接分支 | 无相关技术 | 间接分支预测技术 |
1)条件分支跳转方向预测
在跳转方向预测方面,由于条件分支特有的条件执行属性,该技术预测分支指令是跳转(taken)还是不跳转(not taken)。其他三类分支指令均为非条件执行,因此不需要对跳转方向进行预测。
需要注意的是,对于条件分支,没有必要记录预测分支的目标地址,因为当条件在运行时确定时,目标地址通常编码在指令中。
2)分支目标地址预测
分支地址只有在流水线指令执行阶段才能计算出来,为了避免等待,分支目标地址的预测要求在译码阶段进行对分支的目标指令地址进行预测,进而加快处理器执行速度。
在目标地址预测方面,由于条件分支和立即分支均为直接寻址,目前通过统一的分支目标地址预测技术进行处理;返回分支的目标地址获取,主要通过返回地址预测技术进行处理;间接分支的目标地址获取,主要通过间接分支预测技术进行处理。
分支目标预测不同于条件分支跳转方向预测,分支目标预测指对指令高速缓存中的内容,检测出其中的条件跳转指令与无条件跳转指令,然后为指令高速缓存预装入(prefetch)相应的跳转目标代码块。
03 分支预测部件
1)模式历史表
模式历史表(Pattern History Table ,PHT)用来预测条件分支的未来执行方向。在底层的微体系结构层面,PHT是基于分支指令的虚拟地址位加上一个隐藏的分支历史缓冲区(BranchHistory Buffe,BHB)的组合来访问的,这个隐藏的分支历史缓冲区在相同的物理核心上累积了最后N个分支的全局行为。
if (x < len(array1))
y = array2[array1[x] * 4096];
在体系结构层级,这个程序明确地确保变量x始终位于固定长度缓冲区array1的范围内。但是,在重复提供x的有效值之后,PHT将可靠地预测这个分支的计算结果为true,然后当攻击者提供了一个越界变量x值时,CPU将继续沿着错误预测的路径运行,并临时执行越界内存访问。上面的代码片段提供了一个明确的“泄漏”示例,它可以作为一个微体系结构的隐蔽通道:根据读取的超界值,瞬时指令将另一个属于array2的内存页加载到缓存中。
基于PHT的幽灵攻击主要依赖于一种“相同地址空间在地分支中毒”策略。英特尔、ARM和AMD的处理器测试很容易受到四种PHT误译策略的影响。
2)分支目标缓存区
分支目标缓存区(Branch Target Buffer,BTB)用来在解码分支指令之前预测分支的目标地址。BTB维护一个处理器最近执行的分支指令的地址到目标地址的映射。对于(条件分支和立即分支,处理器使用分支指令的虚拟地址的部分地址位索引BTB,以生成预期的跳转目标。对于返回分支和间接分支,处理器使用不同的机制,在索引BTB时可以考虑BHB中累积的全局分支历史。
基于PHT的幽灵攻击的瞬态指令沿着特定的错误预测路径执行,而基于BTB的幽灵攻击允许将瞬态控制流重定向到任意目的地址。采用类似面向返回编程(ROP)攻击技术和BTB中毒,而不是ROP的应用程序级漏洞,在受害者地址空间中寻找可能的代码片段“gadgets”与攻击者代码链接起来,以构造任意的瞬时指令序列。因此,基于PHT的幽灵攻击的成功关键靠沿着错误预测的代码路径的意外泄漏,基于BTB的幽灵攻击使用的类似于ROP的gadget直接地构造隐蔽通道来暴露来自瞬态域的机密信息。
BTB通常不会在物理核心之间共享,因此处理器只从在同一核心上执行的前一个分支学习。
2)返回堆栈缓冲区
返回堆栈缓冲区(Return Stack Buffer,RSB)用来预测返回地址。RSB是一个每个处理器核的微体系结构缓冲区,它存储最近调用的N个指令的虚拟地址。当遇到ret指令时,处理器从RSB中弹出最上面的元素来预测返回流。
当RSB的布局严重偏离软件堆栈上的实际返回地址时,就会出现错误的推测。例如,在保护域上下文切换时恢复kernel/enclave/user堆栈指针时,会出现这种偏离软件堆栈上的实际返回地址情况。
此外,相同地址空间的攻击者可能会显式地覆盖软件堆栈上的返回地址,或者临时执行更新RSB的调用指令,并且不会产生体系结构层的影响。这就允许在沙箱中执行的不受信任的代码将返回控制流临时转移到沙箱环境之外的代码gadget。
RSB通常不会在物理核心之间共享,因此处理器只从在同一核心上执行的前一个分支学习。
4)存储加载部件
存储加载(Store To Load ,STL)侧重预测数据流中的依赖。存储加载类型(STL)的依赖关系通常要求某一位置的写存储完成之前不应当执行内存加载。然而,在处理器获取管道中所有先前存储的地址之前,处理器会采用消歧部件预测哪些加载可以推测地执行。
当消歧部件预测加载不依赖于先前的存储时,负载将从L1数据缓存中读取数据。当所有先前存储的地址已知时,将验证预测。如果发现任何重叠(overlap),就需要重新加载和执行后续指令。
04 补充知识
Spectre-PHT、Spectre-BTB和Spectre-RSB等类型幽灵攻击基于历史的分支预测(History-based Branch Prediction),是基于控制流的跳转方向和目标地址预测,而Spectre-STL类型的幽灵攻击,是基于数据流的依赖预测。
版权声明:本文为首席安全官Plus原创文章,转载请注明出处,谢谢!
首席安全官Plus是由一群科研院所的网络空间安全研究人员发起成立的民间网络空间安全知识平台,努力打造“有特色、高水平、国际化”的网络安全思想高地。围绕“大数据、云计算和人工智能”等高技术领域的网络安全前沿技术、产业趋势和资本市场,汇聚一流资源,产出一流安全洞见。如投稿,请发送到:csoplus@163.com。
微信二维码