幽灵漏洞(二)
幽灵漏洞变种
1. Indirect Branch Restricted Speculation (ibrs)
当CPUID中存在SPEC_CTRL特性的时候,可以通过"noibrs"/ibrs_enabled来控制IBRS特性。是否支持这个特性可以通过SPEC_CTRL MSR来获取(为什么不使用保存在内存中的变量来控制呢?这个寄存器读取的时候也挺慢的)。
当ibrs_enabled设置为1(也就是spectre_v2=ibrs),内核态将“间接分支限制预测”。当IBRS设置为2(spectre_v2=ibrs_always),那么它同时限制用户态和内核态的“间接分支预测”。当该值设为3的时候(spectre_v2=retpoline,ibrs_user),它仅仅限制用户态“间接分支预测”功能。
读完上面的内容后应该知道为什么使用MSR寄存器了吧。分支预测是CPU的功能,要开启或关闭这个功能,当然只能通过设置CPU的寄存器来达到目的。 分支预测并不是代码中主动去做的事情。因为guest mode和root mode不一定都需要打开或关闭这个功能,所以需要MSR这种特定模式寄存器。
2. Indirect Branch Prediction Barriers (ibpb)
ibpb目前是只读的,它有内核来设置,只有当irbs和retp后才会被设置。与ibrs一样,ibpb也只有在升级了CPU微码后才能设置。如果CPUID中支持IBPB_SUPPORT 或者 SPEC_CTRL的话,那么可以通过控制PRED_CMD MSR来控制IBPB功能。
当ibpb_enabled 设置为1的时候,IBPB barrier会在guest mode或user mode(用户态)的上下文切换的时候去刷新间接分支预测器中的内容,以阻止同主机上的其他虚拟机攻击或是同主机上的其他进程攻击。如果要阻止同主机上的其他虚拟机的攻击,ibrs_enabled设为2也是不够的,还需要设置ibpb_enabled为1。
以上内容翻译自redhat官网。 个人的理解如下:
ibpb:它是一种屏障,类似于内存屏障(内存栅栏),它保证之前的分支预测不会影响到后面的代码,相当于把分支预测器刷空了。
ibpb有助于缓解三种潜在的攻击:
1. 缓解客户机之间的攻击:当guest切换的时候,我们通过执行ibpb来实现。
2. 缓解从guest/ring3到host/ring3的攻击:这通过在主机任务切换或VMEXIT的时候执行ibpb来实现。
MSR(model Specific register):特定模式寄存器。就是每种模式都有自己的值(guest/root mode? 答:是的,甚至是用户态和内核态都可以有不同的值,所以需要反复存取),所以它需要在切换的时候存取一下?
注意IBPB与IBRS不一样,它是一种命令MSR,并且不保留状态,也就是说每次它在完成任务后就被重置了。所以在每次任务切换的时候都需要重新设置。(http://blog.asset-intertech.com/test_data_out/2018/02/spectre-meltdown-and-embedded-msr-access.html)