/Qspectre

指定编译器生成指令以缓解某些 Spectre 变体 1 安全漏洞。

语法

/Qspectre

备注

/Qspectre 选项使编译器能够插入指令以缓解某些 Spectre 安全漏洞。 这些漏洞称为推理执行旁道攻击。 它们会影响许多操作系统和新式处理器,包括 Intel、AMD 和 ARM 的处理器。

从 Visual Studio 2017 版本 15.5.5 和所有更高版本中已提供 /Qspectre 选项。 该选项在 Visual Studio 2015 Update 3 中通过 KB 4338871 提供。

/Qspectre 选项默认处于关闭状态。

在其初始版本中,/Qspectre 选项仅处理优化的代码。 从 Visual Studio 2017 版本 15.7 开始,所有优化级别都支持 /Qspectre 选项。

在包含 Spectre 缓解功能的版本中还提供了多个 Microsoft C++ 库。 可以在 Visual Studio 安装程序中下载适用于 Visual Studio 的 Spectre 缓解库。 可在“单个组件”选项卡下的“编译器、生成工具和运行时”中找到它们,并且它们的名称中含“面向 Spectre 的库”。 启用了缓解功能的 DLL 和静态运行时库均可用于一部分 Visual C++ 运行时:VC++ 启动代码、vcruntime140、msvcp140、concrt140 和 vcamp140。 只有应用程序本地部署支持 DLL。 Visual C++ 运行时库可再发行程序包的内容没有修改。

还可以安装适用于 MFC 和 ATL 的 Spectre 缓解库。 在“单个组件”选项卡中的“SDK、库和框架”下可以找到这些库

注意

没有适用于通用 Windows (UWP) 应用程序或组件的 Spectre 缓解库版本。 无法实现此类库的应用本地部署。

适用性

如果代码对跨信任边界的数据进行操作,建议使用 /Qspectre 选项来重新生成和重新部署代码,以尽快解决此问题。 此类代码的一个示例是加载可能影响执行的不受信任输入的代码。 例如,发出远程过程调用、分析不受信任的输入或文件,或使用其他本地进程间通信 (IPC) 接口的代码。 标准沙盒技术可能还不足以彻底解决问题。 在确定你的代码不跨信任边界之前,请仔细调查沙盒。

可用性

从 Visual Studio 2017 版本 15.5.5 开始提供 /Qspectre 选项,在 2018 年 1 月 23 日及之后对 Microsoft C/C++ 编译器 (MSVC) 做出的所有更新中均提供该选项。 使用 Visual Studio 安装程序更新编译器并安装 Spectre 缓解库作为单独组件。 此外,Visual Studio 2015 Update 3 通过一个修补程序提供 /Qspectre 选项。 有关详细信息,请参阅 KB 4338871

Visual Studio 2017 版本 15.5 的所有版本,以及 Visual Studio 2017 版本 15.6 的所有预览版。 包括一个未记录的选项 /d2guardspecload。 它等效于 /Qspectre 的初始行为。 可以使用 /d2guardspecload 将相同的缓解功能应用于这些版本的编译器中的代码。 我们建议更新生成以在支持 /Qspectre 的编译器中使用该选项。 /Qspectre 选项还能支持更高版本的编译器中的新缓解功能。

效果

/Qspectre 选项输出代码以缓解 Specter 变体 1、绕过边界检查 CVE-2017-5753。 它通过插入充当推理性代码执行屏障的指令进行运作。 用于减轻处理器推理的特定指令取决于处理器及其微体系结构,并且可能在编译器的未来版本中发生变化。

启用 /Qspectre 选项时,编译器会尝试识别推理执行可能在其中绕过边界检查的实例。 这正是它插入屏障指令的位置。 必须知道编译器可以用来识别变体 1 实例的分析限制。 在这种情况下,不能保证检测到 /Qspectre 下变体 1 的所有可能的实例。

性能影响

在多个相当大的代码库中,/Qspectre 对性能的影响似乎可忽略不计。 但是,无法保证代码在 /Qspectre 下的性能仍不受影响。 应对代码进行基准测试,以确定该选项对性能的影响。 如果你知道在性能关键型块或循环中不需要缓解功能,则可以使用 __declspec(spectre(nomitigation)) 指令选择性地禁用缓解功能。 此指令在仅支持 /d2guardspecload 选项的编译器中不可用。

所需的库

/Qspectre 编译器选项可以缓解你自己的代码中的问题。 为了获得更好的保护,我们强烈建议还使用生成的库来提供 Spectre 缓解功能。 Spectre 缓解功能附带多个 Microsoft 运行时库。

以下库是可选组件,必须使用 Visual Studio 安装程序进行安装:

  • 面向 Spectre [(x86 and x64) | (ARM) | (ARM64)] 的 MSVC 版本 version_numbers 库
  • 带有 Spectre 缓解功能的 Visual C++ ATL for [(x86/x64) | ARM | ARM64]
  • 带有 Spectre 缓解功能的 Visual C++ MFC for [x86/x64 | ARM | ARM64]

Visual Studio IDE 中默认的基于 MSBuild 的项目系统允许为项目指定 Spectre 缓解属性。 此属性设置 /Qspectre 编译器选项并更改库路径,以链接 Spectre 缓解运行时库。 如果在生成代码时未安装这些库,则生成系统会报告警告 MSB8040。 如果 MFC 或 ATL 代码生成失败,并且链接器报告错误(例如,错误 LNK1104:无法打开文件“oldnames.lib”),原因可能是缺少这些库。

Visual Studio IDE 中默认的基于 MSBuild 的项目系统允许为项目指定 Spectre 缓解属性。 此属性设置 /Qspectre 编译器选项并更改库路径,以链接 Spectre 缓解运行时库。 如果在生成代码时未安装这些库,则生成系统会报告警告 MSB8038:“启用了 Spectre 缓解,但找不到 Spectre 缓解库”。如果 MFC 或 ATL 代码生成失败,并且链接器报告错误(例如,错误 LNK1104:无法打开文件“oldnames.lib”),原因可能是缺少这些库。

可通过多种方式将 Spectre 缓解库指定到生成命令行。 可以使用 /LIBPATH 链接器选项指定 Spectre 缓解库的路径,使其成为默认库。 可以使用 /NODEFAULTLIB 链接器选项并显式链接 Spectre 缓解库。 或者,可以设置 LIBPATH 环境变量以包含目标平台的 Spectre 缓解库的路径。 在环境中设置此路径的一种方式是使用通过 spectre_mode 选项设置的开发人员命令提示符。 有关详细信息,请参阅在现有命令窗口中使用开发人员工具

x86、x64 和 ARM 平台的 Spectre 缓解运行时库作为修补程序的一部分提供,可通过 KB 4338871 获取。 默认情况下,这些库安装在以下目录中:

  • x86:C:\Program Files (x86)\Microsoft Visual Studio 14.0\VC\lib\spectre
  • x64:C:\Program Files (x86)\Microsoft Visual Studio 14.0\VC\lib\spectre\amd64
  • ARM:C:\Program Files (x86)\Microsoft Visual Studio 14.0\VC\lib\spectre\arm

可通过多种方式将 Spectre 缓解库指定到生成命令行。 可以使用 /LIBPATH 链接器选项指定 Spectre 缓解库的路径,使其成为默认库。 可以使用 /NODEFAULTLIB 链接器选项并显式链接 Spectre 缓解库。 或者,可以设置 LIBPATH 环境变量以包含目标体系结构的 Spectre 缓解库的路径。 有关详细信息,请参阅通过命令行使用 Microsoft C++ 工具集

其他信息

有关详细信息,请参阅官方的 Microsoft Security Advisory ADV180002,用于缓解推理执行旁道漏洞的指南。 也可从 Intel 推理性执行旁道缓解措施 和 ARM 缓存推理旁道获取指南。

有关 Spectre 和 Meltdown 缓解功能的特定于 Windows 概述,请参阅了解 Windows 系统上的 Spectre 和 Meltdown 缓解功能的性能影响

有关 MSVC 缓解功能解决的 Spectre 漏洞的概述,请参阅 C++ 团队博客上的 MSVC 中的 Spectre 缓解功能

在 Visual Studio 开发环境中设置此编译器选项

  1. 打开项目的“属性页” 对话框。 有关详细信息,请参阅在 Visual Studio 中设置 C++ 编译器和生成属性

  2. 选择“配置属性”>“C/C++”>“代码生成”属性页面

  3. 为“Spectre 缓解”属性选择一个新值。 选择“确定”应用更改

  1. 打开项目的“属性页” 对话框。 有关详细信息,请参阅在 Visual Studio 中设置 C++ 编译器和生成属性

  2. 选择“配置属性”>“C/C++”>“命令行”属性页

  3. 在“附加选项”框中输入 /Qspectre 编译器选项。 选择“应用”以应用更改

  4. 选择“配置属性”>“链接器”>“常规”属性页

  5. 对于项目属性中的每个平台,请编辑“其他库目录”属性。 为目标平台设置 Spectre 缓解运行时库目录的路径,然后选择“应用”以应用更改。 完成后,选择“确定”

以编程方式设置此编译器选项

另请参阅

/Qspectre-jmp
/Qspectre-load
/Qspectre-load-cf
/Q 选项(低级别操作)
MSVC 编译器选项
MSVC 编译器命令行语法