繁体   English   中英

幽灵警告MSVC C5040的解决方法

[英]Workaround for Spectre warning MSVC C5040

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;
}

“在上面的例子中,代码执行数组边界检查以确保untrusted_index小于array1的长度。这是确保程序不读取超出数组边界所必需的。虽然这似乎是声音正如所写,它没有考虑涉及推测性执行的CPU的微体系结构行为。“

所以你现在得到一个警告:

警告C5045:如果指定了/ Qspectre开关,编译器将为内存加载插入Spectre缓解

这是告诉你这个代码最终可能比你想要的慢(如果编译/ Qspectre)的方式,因为它会提供一些额外的保护。

既然你似乎没有把任何事情视为理所当然,我怀疑做出“只是让警告消失”的改变 例如,对于我在这里给出的MCVE代码的特定实例,将untrusted_index < array1_length更改为untrusted_index != array1_length似乎就这样做 但这是一个可行的补丁,还是他们的警告只是不完整 - 在下一次更新中,它也会抱怨这个?

我知道我可以使用/ wd5040或其他方式禁用警告。 但我有兴趣确保如果使用/ Qspectre编译代码没有减速,并且如果没有使用/ Qspectre编译则没有警告。 我不想四处寻找在循环条件下改变< to !=文件 - 或者其他什么 - 如果那只是流失。

所以一个更大的问题是,如果存在这种基本的合法解决方案模式,为什么没有提到它们呢? 例如,我描述的情况是一个迭代,我控制索引,而不必担心它来自“不受信任的来源”。 然而我收到了一个警告,从<切换到!=让它消失了。 为什么? 应该有吗?

从文章本身:

值得注意的是,MSVC和编译器在尝试识别变体1的实例时通常可以执行的分析存在限制。因此,无法保证变体1的所有可能实例都将在/ Qspectre下进行检测。

您可能遇到过/ Qspectre的当前实现无法通过设计缓解漏洞的情况之一。 这是合理的,因为过度使用LFENCE可能会显着降低性能。 减轻代码中出现的变体1的每个实例都太昂贵而无法在软件中完全完成(使用LFENCE)。

在评论中,有人问:

您能否为开发人员描述MSVC的限制,以及开发人员需要做些什么来保护自己免受“变体1”的侵害?

该文章的作者回答说:

我们不会详细介绍MSVC的实现。 很多人和公司都依赖我们的工具,因此我们会谨慎对待我们公开讨论的问题。

因此,微软似乎并不想详细披露/ Qspectre不会减少变体1的哪些实例。

如果您不想要警告,只需使用#pragma warning(disable:5040),或在项目属性页面中禁用它。

请注意,您提供的更改为“untrusted_index!= array1_length”是不够的,因为它会使整个范围大于滥用的大小。

请记住,这个诊断只是告诉你编译器会在启用幽灵缓解的情况下做一些不同的事情,它并不是真的告诉你,你必须对代码做任何事情

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM