Enable Control Flow Guard in rustbuild
This commit is contained in:
parent
c58e09f138
commit
87df124ba7
5 changed files with 56 additions and 0 deletions
|
@ -435,6 +435,10 @@
|
||||||
# Use LLVM libunwind as the implementation for Rust's unwinder.
|
# Use LLVM libunwind as the implementation for Rust's unwinder.
|
||||||
#llvm-libunwind = false
|
#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
|
# Options for specific targets
|
||||||
#
|
#
|
||||||
|
|
|
@ -1111,6 +1111,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
|
// For `cargo doc` invocations, make rustdoc print the Rust version into the docs
|
||||||
cargo.env("RUSTDOC_CRATE_VERSION", self.rust_version());
|
cargo.env("RUSTDOC_CRATE_VERSION", self.rust_version());
|
||||||
|
|
||||||
|
|
|
@ -116,6 +116,7 @@ pub struct Config {
|
||||||
pub targets: Vec<Interned<String>>,
|
pub targets: Vec<Interned<String>>,
|
||||||
pub local_rebuild: bool,
|
pub local_rebuild: bool,
|
||||||
pub jemalloc: bool,
|
pub jemalloc: bool,
|
||||||
|
pub control_flow_guard: bool,
|
||||||
|
|
||||||
// dist misc
|
// dist misc
|
||||||
pub dist_sign_folder: Option<PathBuf>,
|
pub dist_sign_folder: Option<PathBuf>,
|
||||||
|
@ -332,6 +333,7 @@ struct Rust {
|
||||||
jemalloc: Option<bool>,
|
jemalloc: Option<bool>,
|
||||||
test_compare_mode: Option<bool>,
|
test_compare_mode: Option<bool>,
|
||||||
llvm_libunwind: Option<bool>,
|
llvm_libunwind: Option<bool>,
|
||||||
|
control_flow_guard: Option<bool>,
|
||||||
}
|
}
|
||||||
|
|
||||||
/// TOML representation of how each build target is configured.
|
/// TOML representation of how each build target is configured.
|
||||||
|
@ -578,6 +580,7 @@ impl Config {
|
||||||
set(&mut config.rust_verify_llvm_ir, rust.verify_llvm_ir);
|
set(&mut config.rust_verify_llvm_ir, rust.verify_llvm_ir);
|
||||||
config.rust_thin_lto_import_instr_limit = rust.thin_lto_import_instr_limit;
|
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.rust_remap_debuginfo, rust.remap_debuginfo);
|
||||||
|
set(&mut config.control_flow_guard, rust.control_flow_guard);
|
||||||
|
|
||||||
if let Some(ref backends) = rust.codegen_backends {
|
if let Some(ref backends) = rust.codegen_backends {
|
||||||
config.rust_codegen_backends =
|
config.rust_codegen_backends =
|
||||||
|
|
|
@ -60,6 +60,7 @@ o("lld", "rust.lld", "build lld")
|
||||||
o("lldb", "rust.lldb", "build lldb")
|
o("lldb", "rust.lldb", "build lldb")
|
||||||
o("missing-tools", "dist.missing-tools", "allow failures when building tools")
|
o("missing-tools", "dist.missing-tools", "allow failures when building tools")
|
||||||
o("use-libcxx", "llvm.use-libcxx", "build LLVM with libc++")
|
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("cflags", "llvm.cflags", "build LLVM with these extra compiler flags")
|
||||||
o("cxxflags", "llvm.cxxflags", "build LLVM with these extra compiler flags")
|
o("cxxflags", "llvm.cxxflags", "build LLVM with these extra compiler flags")
|
||||||
|
|
|
@ -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.
|
Loading…
Add table
Reference in a new issue