Visual Studio 2017版本15.7预览版4 为我们的Spectre缓解增加了一个新功能:查看编译器将在何处插入缓解以及哪些数据导致了该操作。一个新的警告C5045让您可以看到代码中的哪些模式会导致插入一个缓解措施,例如LFENCE。
这一变化建立在我们现有的幽灵缓解支持的基础上,包括 预览3中引入的更改 . 有关的完整详细信息可在原文的上下文中找到 MSVC幽灵缓解站 在VCBlog上。新的警告也将在下面讨论。
启用C5045
默认情况下,C5045警告处于关闭状态。您可以通过以下两种方式之一启用它:
- 将警告级别设置为项目属性> C/C++ >“一般>警告级别”中的“允许警告”。此选项启用所有警告,因此可能有点嘈杂。即使是VC++库也不会试图清除所有警告(
/Wall
). - 将C5045的警告级别设置为“警告级别”设置中指定的级别。C++项目的默认级别为
/W3
,因此可以将C5045的警告级别设置为级别3/w35045
在命令行上:它将警告号5045作为级别3对待。您可以在ProjkProjts> C/C++命令行中的文本框中执行此操作>附加选项。
使用C5045
一旦您启用了警告,只需编译您的代码以查看将在何处插入缓解措施。此代码示例包含一个漏洞:
int G, G1, G2; __forceinline int * bar(int **p, int i) { return p[i]; } __forceinline void bar1(int ** p, int i) { if (i < G1) { auto x = p[i]; // mitigation here G = *x; } } __forceinline void foo(int * p) { G = *p; } void baz(int ** p, int i) { if (i < G1) { foo(bar(p, i + G2)); } bar1(p, i); } int main() { }
编译上面的代码表明,应该在第13行插入一个缓解措施 i
在第12行上输入第14行上的内存负载 bar
和 bar1
但如果放在12号线,缓解措施是有效的。
1>------ Rebuild All started: Project: Spectre, Configuration: Debug Win32 ------ 1>Source.cpp 1>c:usersapardoesource eposspectrespectresource.cpp(13): warning C5045: Compiler will insert Spectre mitigation for memory load if /Qspectre switch specified 1>c:usersapardoesource eposspectrespectresource.cpp(12) : note: index 'i' range checked by comparison on this line 1>c:usersapardoesource eposspectrespectresource.cpp(14) : note: feeds memory load on this line 1>Spectre.vcxproj -> c:Usersapardoesource eposSpectreDebugSpectre.exe 1>Done building project "Spectre.vcxproj". ========== Rebuild All: 1 succeeded, 0 failed, 0 skipped ==========
请注意,此警告纯粹是信息性的:除非使用 /Qspectre
开关。C5045的功能独立于 /Qspectre
切换,以便可以在同一编译中同时使用它们。
最后
我们MSVC团队致力于持续改进您的Windows软件并保证其安全性。我们将继续开发技术,帮助开发人员缓解投机性执行端通道漏洞和其他安全问题。
我们鼓励您尽快重新编译并重新部署易受攻击的软件。继续看这个博客和 @visualc Twitter订阅源 有关此主题的更新。
如果您有任何问题,请随时问我们下面。您也可以通过电子邮件将您的意见发送给我们 visualcpp@microsoft.com ,通过 推特@visualc ,或Facebook Microsoft Visual Cpp . 非常感谢。