Hos*_*ork 12 c visual-c++ visual-studio-2017 spectre
MSVC刚刚发布了一个更新,它添加了一个关于编译器将注入的一些代码的新警告,以缓解(显然是一些小的)Spectre:
https://blogs.msdn.microsoft.com/vcblog/2018/01/15/spectre-mitigations-in-msvc/
这是一个来自他们的"有问题"代码示例的小MCVE:
#include <stdio.h>
int main(int argc, char *argv) {
unsigned char array1[1] = {0};
int array1_length = 1;
unsigned char array2[1] = {99};
int untrusted_index = 0; /* in this MCVE, I trust it, compiler doesn't */
for (; untrusted_index < array1_length; ++untrusted_index) {
unsigned char value = array1[untrusted_index];
unsigned char value2 = array2[value * 64];
printf("Picked value %d\n", value2);
}
return 0;
}
Run Code Online (Sandbox Code Playgroud)
"在上面的例子中,代码执行数组边界检查以确保untrusted_index小于array1的长度.这是确保程序不读取超出数组边界所必需的.虽然这似乎是声音正如所写,它没有考虑涉及推测性执行的CPU的微体系结构行为."
所以你现在得到一个警告:
警告C5045:如果指定了/ Qspectre开关,编译器将为内存加载插入Spectre缓解
这是告诉你这个代码最终可能比你想要的慢(如果编译/ Qspectre)的方式,因为它会提供一些额外的保护.
既然你似乎没有把任何事情视为理所当然,我怀疑做出"只是让警告消失"的改变.例如,untrusted_index < array1_length
改为untrusted_index != array1_length
似乎这样做,对于我在这里给出的MCVE代码的特定实例.但这是一个可行的补丁,还是他们的警告只是不完整 - 在下一次更新中,它也会抱怨这个?
我知道我可以使用/ wd5040或其他方式禁用警告.但我有兴趣确保如果使用/ Qspectre编译代码没有减速,并且如果没有使用/ Qspectre编译则没有警告.我不想去触摸周围不断变化的文件<
,以!=
在循环的条件-无论-如果这只是翻腾.
所以一个更大的问题是,如果存在这种基本的合法解决方案模式,为什么没有提到它们呢?例如,我描述的情况是一个迭代,我控制索引,而不必担心它来自"不受信任的来源".然而,我得到了一个警告,并且在切换<
至!=
使其消失.为什么?应该有吗?
如果您不希望出现警告,只需使用#pragma warning(disable :5040),或在项目属性页中禁用它。
请注意,您对“untrusted_index!= array1_length”提供的更改是不够的,因为它使整个范围大于可被滥用的大小。
请记住,此诊断只是告诉您,在启用幽灵缓解功能的情况下,编译器将执行与以前不同的操作,它并不是真正告诉您必须对代码执行任何操作。
归档时间: |
|
查看次数: |
1309 次 |
最近记录: |