Grand Schemozzle:幽灵(Spectre)继续作怪

幽灵V1硬件缺陷一般以允许通过推测执行绕过数组边界检查作为特征。如果这是真的,那么它将不会是这一类漏洞所允许的诡计的全部范围。为表明这个事实,就需要看一下"SWAPGS 漏洞",由CVE-2019-1125开始广为人知,也被linux内核解决它的开发组人员称作"Grand Schemozzle"

Segment(段)差不多是可以追溯到x86时代最早起的架构遗迹,在很大程度上,他没有在64位世界留存下来。这就是说,少量的Segment还存在于特定的任务;那些还包含GS和FS的任务。当前Linux系统对GS最普遍的应用是为thread-local或cpu-local存储;在内核,GS片段指向per-cpu区域,用户态是允许使用它自己的GS的,arch_prctl()系统调用可以被用于修改这个值。

正如人们所预料,内核需要注意使用自己的GS指针而不是用户空间搞出的指针。x86架构乖乖的提供了一个指令,SWAPGS,来使其相对容易。在进入内核,一个SWAPGS指令将会交换当前GS段指针为一个特定值(MSR中的);回到用户态之前又会执行SWAPGS,将用户态的GS值换回去。一些小心放置的SWAPGS指令将会因此防止内核运行别的GS指针的下的东西。

可能有人会想,并不是所有进入内核代码的入口都是来自用户态。运行SWAPGS时,如果系统已经运行在内核态的话,是会出问题的,因此内核中的实际代码大多数情况下都是:

if(!in_kernel_mode()) SWAPGS

而这就是出现问题的点了。如果上述代码被预测运行,处理器将会对于是否执行SWAPGS做出错误的决定,进而运行错误的GS段指针。两种方向的推测执行都可能导致错误:CPU推测是用户态,将会直接用用户态GS执行而不SWAPGS,而如果系统已经是内核态了,CPU却可能会推测错误,然后执行SWAPGS,因此用户态GS值被推测执行;系统已经在内核态了,就会不执行SWAPGS。无论哪种方式,随后的per-cpu数据的引用都会推测重映射到一个用户态的地址。这就通过普通的侧信道技术的方式制造了数据泄露。

你可能感兴趣的:(Grand Schemozzle:幽灵(Spectre)继续作怪)