Skip to content

Commit b61f3bb

Browse files
authored
Rollup merge of rust-lang#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 rust-lang#68793.
2 parents 77a74ec + d282fb0 commit b61f3bb

File tree

1 file changed

+31
-7
lines changed

1 file changed

+31
-7
lines changed

src/doc/unstable-book/src/compiler-flags/control-flow-guard.md

+31-7
Original file line numberDiff line numberDiff line change
@@ -4,30 +4,54 @@ The tracking issue for this feature is: [#68793](https://github.com/rust-lang/ru
44

55
------------------------
66

7-
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.
7+
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.
88

9-
[cfguard-docs]: https://docs.microsoft.com/en-us/windows/win32/secbp/control-flow-guard
9+
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.
1010

11-
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.
11+
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.
1212

13-
It is strongly recommended to also enable Control Flow Guard checks in all linked libraries, including the standard library.
13+
In terms of interoperability:
14+
- 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.
15+
- 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).
1416

15-
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.
17+
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.
18+
19+
20+
## When to use Control Flow Guard
21+
22+
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
23+
24+
25+
## Overhead of Control Flow Guard
26+
27+
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%.
28+
29+
30+
## Testing Control Flow Guard
31+
32+
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.
33+
34+
35+
## Control Flow Guard in libraries
36+
37+
It is strongly recommended to also enable CFG checks for all linked libraries, including the standard library.
38+
39+
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.
1640

1741
[build-std]: https://doc.rust-lang.org/nightly/cargo/reference/unstable.html#build-std
1842

1943
For example:
2044
```cmd
2145
rustup toolchain install --force nightly
2246
rustup component add rust-src
23-
SET RUSTFLAGS=-Zcontrol_flow_guard=checks
47+
SET RUSTFLAGS=-Z control_flow_guard=checks
2448
cargo +nightly build -Z build-std --target x86_64-pc-windows-msvc
2549
```
2650

2751
```PowerShell
2852
rustup toolchain install --force nightly
2953
rustup component add rust-src
30-
$Env:RUSTFLAGS = "-Zcontrol_flow_guard=checks"
54+
$Env:RUSTFLAGS = "-Z control_flow_guard=checks"
3155
cargo +nightly build -Z build-std --target x86_64-pc-windows-msvc
3256
```
3357

0 commit comments

Comments
 (0)