Rollup merge of #68824 - ajpaverd:cfguard-rustbuild, r=Mark-Simulacrum

Enable Control Flow Guard in rustbuild

Now that Rust supports Control Flow Guard (#68180), add a config.toml option to build the standard library with CFG enabled.

r? @nagisa
This commit is contained in:
Dylan DPC 2020-02-11 16:36:57 +01:00 committed by GitHub
commit c8c2b2bc54
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 56 additions and 0 deletions

View File

@ -444,6 +444,10 @@
# Use LLVM libunwind as the implementation for Rust's unwinder.
#llvm-libunwind = false
# Enable Windows Control Flow Guard checks in the standard library.
# This only applies from stage 1 onwards, and only for Windows targets.
#control-flow-guard = false
# =============================================================================
# Options for specific targets
#

View File

@ -1135,6 +1135,20 @@ impl<'a> Builder<'a> {
);
}
// If Control Flow Guard is enabled, pass the `control_flow_guard=checks` flag to rustc
// when compiling the standard library, since this might be linked into the final outputs
// produced by rustc. Since this mitigation is only available on Windows, only enable it
// for the standard library in case the compiler is run on a non-Windows platform.
// This is not needed for stage 0 artifacts because these will only be used for building
// the stage 1 compiler.
if cfg!(windows)
&& mode == Mode::Std
&& self.config.control_flow_guard
&& compiler.stage >= 1
{
rustflags.arg("-Zcontrol_flow_guard=checks");
}
// For `cargo doc` invocations, make rustdoc print the Rust version into the docs
cargo.env("RUSTDOC_CRATE_VERSION", self.rust_version());

View File

@ -116,6 +116,7 @@ pub struct Config {
pub targets: Vec<Interned<String>>,
pub local_rebuild: bool,
pub jemalloc: bool,
pub control_flow_guard: bool,
// dist misc
pub dist_sign_folder: Option<PathBuf>,
@ -333,6 +334,7 @@ struct Rust {
jemalloc: Option<bool>,
test_compare_mode: Option<bool>,
llvm_libunwind: Option<bool>,
control_flow_guard: Option<bool>,
}
/// TOML representation of how each build target is configured.
@ -580,6 +582,7 @@ impl Config {
set(&mut config.rust_verify_llvm_ir, rust.verify_llvm_ir);
config.rust_thin_lto_import_instr_limit = rust.thin_lto_import_instr_limit;
set(&mut config.rust_remap_debuginfo, rust.remap_debuginfo);
set(&mut config.control_flow_guard, rust.control_flow_guard);
if let Some(ref backends) = rust.codegen_backends {
config.rust_codegen_backends =

View File

@ -60,6 +60,7 @@ o("lld", "rust.lld", "build lld")
o("lldb", "rust.lldb", "build lldb")
o("missing-tools", "dist.missing-tools", "allow failures when building tools")
o("use-libcxx", "llvm.use-libcxx", "build LLVM with libc++")
o("control-flow-guard", "rust.control-flow-guard", "Enable Control Flow Guard")
o("cflags", "llvm.cflags", "build LLVM with these extra compiler flags")
o("cxxflags", "llvm.cxxflags", "build LLVM with these extra compiler flags")

View File

@ -0,0 +1,34 @@
# `control_flow_guard`
The tracking issue for this feature is: [#68793](https://github.com/rust-lang/rust/issues/68793).
------------------------
The `-Zcontrol_flow_guard=checks` compiler flag enables the Windows [Control Flow Guard][cfguard-docs] platform security feature. When enabled, the compiler outputs a list of valid indirect call targets, and inserts runtime checks on all indirect jump instructions to ensure that the destination is in the list of valid call targets.
[cfguard-docs]: https://docs.microsoft.com/en-us/windows/win32/secbp/control-flow-guard
For testing purposes, the `-Zcontrol_flow_guard=nochecks` compiler flag can be used to emit only the list of valid call targets, but not the runtime checks.
It is strongly recommended to also enable Control Flow Guard checks in all linked libraries, including the standard library.
To enable Control Flow Guard in the standard library, you can use the [cargo `-Zbuild-std` functionality][build-std] to recompile the standard library with the same configuration options as the main program.
[build-std]: https://doc.rust-lang.org/nightly/cargo/reference/unstable.html#build-std
For example:
```cmd
rustup toolchain install --force nightly
rustup component add rust-src
SET RUSTFLAGS=-Zcontrol_flow_guard=checks
cargo +nightly build -Z build-std --target x86_64-pc-windows-msvc
```
```PowerShell
rustup toolchain install --force nightly
rustup component add rust-src
$Env:RUSTFLAGS = "-Zcontrol_flow_guard=checks"
cargo +nightly build -Z build-std --target x86_64-pc-windows-msvc
```
Alternatively, if you are building the standard library from source, you can set `control-flow-guard = true` in the config.toml file.