在谷歌的 Spectre/Meltdown 项目零博客条目之后,有这段代码可以说明攻击:
struct array {
unsigned long length;
unsigned char data[];
};
struct array *arr1 = ...; /* small array */
struct array *arr2 = ...; /* array of size 0x400 */
/* >0x400 (OUT OF BOUNDS!) */
unsigned long untrusted_offset_from_caller = ...;
if (untrusted_offset_from_caller < arr1->length) {
unsigned char value = arr1->data[untrusted_offset_from_caller];
unsigned long index2 = ((value&1)*0x100)+0x200;
if (index2 < arr2->length) {
unsigned char value2 = arr2->data[index2];
}
}
说明CPU后面的推测执行,会尝试执行到
arr2->data[index2];
在达到条件之前
if (untrusted_offset_from_caller < arr1->length) {
这将阻止访问区域内存的边界。
我的问题是:
- 如果代码试图明确地这样做,什么会阻止在正常执行中访问该内存区域?
我想在某些地方,操作系统和/或 cpu 内存访问检查应该停止这种情况,并且推测性的 exec 只是跳过那个(?)。
似乎修补那个(实际上没有做的)检查(如果我之前的猜测是正确的......)是不够的或者不是正确的方法,因为已经说过需要另外两个条件:刷新分支预测器 &考虑到分支指令的完整地址(现在 CPU 似乎不这样做了),但是:
- 检查(如果第一个问题的答案是需要额外检查)或“冲洗”对性能的影响不是吗?如果有,估计有多少?(当那些假定的 CPU 将/将被制造时)。