mirror of
https://github.com/rust-lang/rust.git
synced 2024-11-25 16:24:46 +00:00
Rollup merge of #72945 - ajpaverd:cfguard-docs, r=Mark-Simulacrum
Updated documentation for Control Flow Guard Update user-facing documentation for the Control Flow Guard (CFG) exploit mitigation in the unstable book, as requested in #68793.
This commit is contained in:
commit
b61f3bb66b
@ -4,15 +4,39 @@ The tracking issue for this feature is: [#68793](https://github.com/rust-lang/ru
|
||||
|
||||
------------------------
|
||||
|
||||
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.
|
||||
The rustc flag `-Z control_flow_guard=checks` enables the Windows [Control Flow Guard](https://docs.microsoft.com/en-us/windows/win32/secbp/control-flow-guard) (CFG) platform security feature.
|
||||
|
||||
[cfguard-docs]: https://docs.microsoft.com/en-us/windows/win32/secbp/control-flow-guard
|
||||
CFG is an exploit mitigation designed to enforce control-flow integrity for software running on supported Windows platforms (Windows 8.1 onwards). Specifically, CFG uses runtime checks to validate the target address of every indirect call/jump before allowing the call to complete.
|
||||
|
||||
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.
|
||||
During compilation, the compiler identifies all indirect calls/jumps and adds CFG checks. It also emits metadata containing the relative addresses of all address-taken functions. At runtime, if the binary is run on a CFG-aware operating system, the loader uses the CFG metadata to generate a bitmap of the address space and marks those addresses that contain valid targets. On each indirect call, the inserted check determines whether the target address is marked in this bitmap. If the target is not valid, the process is terminated.
|
||||
|
||||
It is strongly recommended to also enable Control Flow Guard checks in all linked libraries, including the standard library.
|
||||
In terms of interoperability:
|
||||
- Code compiled with CFG enabled can be linked with libraries and object files that are not compiled with CFG. In this case, a CFG-aware linker can identify address-taken functions in the non-CFG libraries.
|
||||
- Libraries compiled with CFG can linked into non-CFG programs. In this case, the CFG runtime checks in the libraries are not used (i.e. the mitigation is completely disabled).
|
||||
|
||||
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.
|
||||
CFG functionality is completely implemented in the LLVM backend and is supported for X86 (32-bit and 64-bit), ARM, and Aarch64 targets. The rustc flag adds the relevant LLVM module flags to enable the feature. This flag will be ignored for all non-Windows targets.
|
||||
|
||||
|
||||
## When to use Control Flow Guard
|
||||
|
||||
The primary motivation for enabling CFG in Rust is to enhance security when linking against non-Rust code, especially C/C++ code. To achieve full CFG protection, all indirect calls (including any from Rust code) must have the appropriate CFG checks, as added by this flag. CFG can also improve security for Rust code that uses the `unsafe` keyword
|
||||
|
||||
|
||||
## Overhead of Control Flow Guard
|
||||
|
||||
The CFG checks and metadata can potentially increase binary size and runtime overhead. The magnitude of any increase depends on the number and frequency of indirect calls. For example, enabling CFG for the Rust standard library increases binary size by approximately 0.14%. Enabling CFG in the SPEC CPU 2017 Integer Speed benchmark suite (compiled with Clang/LLVM) incurs approximate runtime overheads of between 0% and 8%, with a geometric mean of 2.9%.
|
||||
|
||||
|
||||
## Testing Control Flow Guard
|
||||
|
||||
The rustc flag `-Z control_flow_guard=nochecks` instructs LLVM to emit the list of valid call targets without inserting runtime checks. This flag should only be used for testing purposes as it does not provide security enforcement.
|
||||
|
||||
|
||||
## Control Flow Guard in libraries
|
||||
|
||||
It is strongly recommended to also enable CFG checks for all linked libraries, including the standard library.
|
||||
|
||||
To enable CFG in the standard library, use the [cargo `-Z build-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
|
||||
|
||||
@ -20,14 +44,14 @@ For example:
|
||||
```cmd
|
||||
rustup toolchain install --force nightly
|
||||
rustup component add rust-src
|
||||
SET RUSTFLAGS=-Zcontrol_flow_guard=checks
|
||||
SET RUSTFLAGS=-Z control_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"
|
||||
$Env:RUSTFLAGS = "-Z control_flow_guard=checks"
|
||||
cargo +nightly build -Z build-std --target x86_64-pc-windows-msvc
|
||||
```
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user