Update documentation for LLVM CFI support
This commit updates the documentation for the LLVM Control Flow Integrity (CFI) support in the Rust compiler (see #95548 and #89653).
This commit is contained in:
parent
5ad7a646a5
commit
f792f26a38
1 changed files with 84 additions and 28 deletions
|
@ -191,7 +191,8 @@ Shadow byte legend (one shadow byte represents 8 application bytes):
|
||||||
|
|
||||||
The LLVM Control Flow Integrity (CFI) support in the Rust compiler initially
|
The LLVM Control Flow Integrity (CFI) support in the Rust compiler initially
|
||||||
provides forward-edge control flow protection for Rust-compiled code only by
|
provides forward-edge control flow protection for Rust-compiled code only by
|
||||||
aggregating function pointers in groups identified by their number of arguments.
|
aggregating function pointers in groups identified by their return and parameter
|
||||||
|
types.
|
||||||
|
|
||||||
Forward-edge control flow protection for C or C++ and Rust -compiled code "mixed
|
Forward-edge control flow protection for C or C++ and Rust -compiled code "mixed
|
||||||
binaries" (i.e., for when C or C++ and Rust -compiled code share the same
|
binaries" (i.e., for when C or C++ and Rust -compiled code share the same
|
||||||
|
@ -243,7 +244,7 @@ fn do_twice(f: fn(i32) -> i32, arg: i32) -> i32 {
|
||||||
fn main() {
|
fn main() {
|
||||||
let answer = do_twice(add_one, 5);
|
let answer = do_twice(add_one, 5);
|
||||||
|
|
||||||
println!("The answer is: {answer}");
|
println!("The answer is: {}", answer);
|
||||||
|
|
||||||
println!("With CFI enabled, you should not see the next answer");
|
println!("With CFI enabled, you should not see the next answer");
|
||||||
let f: fn(i32) -> i32 = unsafe {
|
let f: fn(i32) -> i32 = unsafe {
|
||||||
|
@ -253,18 +254,18 @@ fn main() {
|
||||||
};
|
};
|
||||||
let next_answer = do_twice(f, 5);
|
let next_answer = do_twice(f, 5);
|
||||||
|
|
||||||
println!("The next answer is: {next_answer}");
|
println!("The next answer is: {}", next_answer);
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
Fig. 1. Modified example from the [Advanced Functions and
|
Fig. 1. Modified example from the [Advanced Functions and
|
||||||
Closures][rust-book-ch19-05] chapter of the [The Rust Programming
|
Closures][rust-book-ch19-05] chapter of the [The Rust Programming
|
||||||
Language][rust-book] book.
|
Language][rust-book] book.
|
||||||
|
|
||||||
[//]: # (FIXME: Replace with output from cargo using nightly when #89652 is merged)
|
|
||||||
|
|
||||||
```shell
|
```shell
|
||||||
$ rustc rust_cfi.rs -o rust_cfi
|
$ cargo run --release
|
||||||
$ ./rust_cfi
|
Compiling rust-cfi-1 v0.1.0 (/home/rcvalle/rust-cfi-1)
|
||||||
|
Finished release [optimized] target(s) in 0.76s
|
||||||
|
Running `target/release/rust-cfi-1`
|
||||||
The answer is: 12
|
The answer is: 12
|
||||||
With CFI enabled, you should not see the next answer
|
With CFI enabled, you should not see the next answer
|
||||||
The next answer is: 14
|
The next answer is: 14
|
||||||
|
@ -272,11 +273,11 @@ $
|
||||||
```
|
```
|
||||||
Fig. 2. Build and execution of the modified example with LLVM CFI disabled.
|
Fig. 2. Build and execution of the modified example with LLVM CFI disabled.
|
||||||
|
|
||||||
[//]: # (FIXME: Replace with output from cargo using nightly when #89652 is merged)
|
|
||||||
|
|
||||||
```shell
|
```shell
|
||||||
$ rustc -Clto -Zsanitizer=cfi rust_cfi.rs -o rust_cfi
|
$ RUSTFLAGS="-Zsanitizer=cfi -Cembed-bitcode=yes -Clto" cargo run --release
|
||||||
$ ./rust_cfi
|
Compiling rust-cfi-1 v0.1.0 (/home/rcvalle/rust-cfi-1)
|
||||||
|
Finished release [optimized] target(s) in 3.39s
|
||||||
|
Running `target/release/rust-cfi-1`
|
||||||
The answer is: 12
|
The answer is: 12
|
||||||
With CFI enabled, you should not see the next answer
|
With CFI enabled, you should not see the next answer
|
||||||
Illegal instruction
|
Illegal instruction
|
||||||
|
@ -306,25 +307,25 @@ fn do_twice(f: fn(i32) -> i32, arg: i32) -> i32 {
|
||||||
fn main() {
|
fn main() {
|
||||||
let answer = do_twice(add_one, 5);
|
let answer = do_twice(add_one, 5);
|
||||||
|
|
||||||
println!("The answer is: {answer}");
|
println!("The answer is: {}", answer);
|
||||||
|
|
||||||
println!("With CFI enabled, you should not see the next answer");
|
println!("With CFI enabled, you should not see the next answer");
|
||||||
let f: fn(i32) -> i32 =
|
let f: fn(i32) -> i32 =
|
||||||
unsafe { mem::transmute::<*const u8, fn(i32) -> i32>(add_two as *const u8) };
|
unsafe { mem::transmute::<*const u8, fn(i32) -> i32>(add_two as *const u8) };
|
||||||
let next_answer = do_twice(f, 5);
|
let next_answer = do_twice(f, 5);
|
||||||
|
|
||||||
println!("The next answer is: {next_answer}");
|
println!("The next answer is: {}", next_answer);
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
Fig. 4. Another modified example from the [Advanced Functions and
|
Fig. 4. Another modified example from the [Advanced Functions and
|
||||||
Closures][rust-book-ch19-05] chapter of the [The Rust Programming
|
Closures][rust-book-ch19-05] chapter of the [The Rust Programming
|
||||||
Language][rust-book] book.
|
Language][rust-book] book.
|
||||||
|
|
||||||
[//]: # (FIXME: Replace with output from cargo using nightly when #89652 is merged)
|
|
||||||
|
|
||||||
```shell
|
```shell
|
||||||
$ rustc rust_cfi.rs -o rust_cfi
|
$ cargo run --release
|
||||||
$ ./rust_cfi
|
Compiling rust-cfi-2 v0.1.0 (/home/rcvalle/rust-cfi-2)
|
||||||
|
Finished release [optimized] target(s) in 0.76s
|
||||||
|
Running `target/release/rust-cfi-2`
|
||||||
The answer is: 12
|
The answer is: 12
|
||||||
With CFI enabled, you should not see the next answer
|
With CFI enabled, you should not see the next answer
|
||||||
The next answer is: 14
|
The next answer is: 14
|
||||||
|
@ -332,11 +333,11 @@ $
|
||||||
```
|
```
|
||||||
Fig. 5. Build and execution of the modified example with LLVM CFI disabled.
|
Fig. 5. Build and execution of the modified example with LLVM CFI disabled.
|
||||||
|
|
||||||
[//]: # (FIXME: Replace with output from cargo using nightly when #89652 is merged)
|
|
||||||
|
|
||||||
```shell
|
```shell
|
||||||
$ rustc -Clto -Zsanitizer=cfi rust_cfi.rs -o rust_cfi
|
$ RUSTFLAGS="-Zsanitizer=cfi -Cembed-bitcode=yes -Clto" cargo run --release
|
||||||
$ ./rust_cfi
|
Compiling rust-cfi-2 v0.1.0 (/home/rcvalle/rust-cfi-2)
|
||||||
|
Finished release [optimized] target(s) in 3.38s
|
||||||
|
Running `target/release/rust-cfi-2`
|
||||||
The answer is: 12
|
The answer is: 12
|
||||||
With CFI enabled, you should not see the next answer
|
With CFI enabled, you should not see the next answer
|
||||||
Illegal instruction
|
Illegal instruction
|
||||||
|
@ -346,14 +347,69 @@ Fig. 6. Build and execution of the modified example with LLVM CFI enabled.
|
||||||
|
|
||||||
When LLVM CFI is enabled, if there are any attempts to change/hijack control
|
When LLVM CFI is enabled, if there are any attempts to change/hijack control
|
||||||
flow using an indirect branch/call to a function with different number of
|
flow using an indirect branch/call to a function with different number of
|
||||||
arguments than intended/passed in the call/branch site, the execution is also
|
parameters than arguments intended/passed in the call/branch site, the
|
||||||
terminated (see Fig. 6).
|
execution is also terminated (see Fig. 6).
|
||||||
|
|
||||||
Forward-edge control flow protection not only by aggregating function pointers
|
```rust
|
||||||
in groups identified by their number of arguments, but also their argument
|
use std::mem;
|
||||||
types, will also be provided in later work by defining and using compatible type
|
|
||||||
identifiers (see Type metadata in the design document in the tracking
|
fn add_one(x: i32) -> i32 {
|
||||||
issue [#89653](https://github.com/rust-lang/rust/issues/89653)).
|
x + 1
|
||||||
|
}
|
||||||
|
|
||||||
|
fn add_two(x: i64) -> i64 {
|
||||||
|
x + 2
|
||||||
|
}
|
||||||
|
|
||||||
|
fn do_twice(f: fn(i32) -> i32, arg: i32) -> i32 {
|
||||||
|
f(arg) + f(arg)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn main() {
|
||||||
|
let answer = do_twice(add_one, 5);
|
||||||
|
|
||||||
|
println!("The answer is: {}", answer);
|
||||||
|
|
||||||
|
println!("With CFI enabled, you should not see the next answer");
|
||||||
|
let f: fn(i32) -> i32 =
|
||||||
|
unsafe { mem::transmute::<*const u8, fn(i32) -> i32>(add_two as *const u8) };
|
||||||
|
let next_answer = do_twice(f, 5);
|
||||||
|
|
||||||
|
println!("The next answer is: {}", next_answer);
|
||||||
|
}
|
||||||
|
```
|
||||||
|
Fig. 7. Another modified example from the [Advanced Functions and
|
||||||
|
Closures][rust-book-ch19-05] chapter of the [The Rust Programming
|
||||||
|
Language][rust-book] book.
|
||||||
|
|
||||||
|
```shell
|
||||||
|
cargo run --release
|
||||||
|
Compiling rust-cfi-3 v0.1.0 (/home/rcvalle/rust-cfi-3)
|
||||||
|
Finished release [optimized] target(s) in 0.74s
|
||||||
|
Running `target/release/rust-cfi-3`
|
||||||
|
The answer is: 12
|
||||||
|
With CFI enabled, you should not see the next answer
|
||||||
|
The next answer is: 14
|
||||||
|
$
|
||||||
|
```
|
||||||
|
Fig. 8. Build and execution of the modified example with LLVM CFI disabled.
|
||||||
|
|
||||||
|
```shell
|
||||||
|
$ RUSTFLAGS="-Zsanitizer=cfi -Cembed-bitcode=yes -Clto" cargo run --release
|
||||||
|
Compiling rust-cfi-3 v0.1.0 (/home/rcvalle/rust-cfi-3)
|
||||||
|
Finished release [optimized] target(s) in 3.40s
|
||||||
|
Running `target/release/rust-cfi-3`
|
||||||
|
The answer is: 12
|
||||||
|
With CFI enabled, you should not see the next answer
|
||||||
|
Illegal instruction
|
||||||
|
$
|
||||||
|
```
|
||||||
|
Fig. 9. Build and execution of the modified example with LLVM CFI enabled.
|
||||||
|
|
||||||
|
When LLVM CFI is enabled, if there are any attempts to change/hijack control
|
||||||
|
flow using an indirect branch/call to a function with different return and
|
||||||
|
parameter types than the return type expected and arguments intended/passed in
|
||||||
|
the call/branch site, the execution is also terminated (see Fig. 9).
|
||||||
|
|
||||||
[rust-book-ch19-05]: https://doc.rust-lang.org/book/ch19-05-advanced-functions-and-closures.html
|
[rust-book-ch19-05]: https://doc.rust-lang.org/book/ch19-05-advanced-functions-and-closures.html
|
||||||
[rust-book]: https://doc.rust-lang.org/book/title-page.html
|
[rust-book]: https://doc.rust-lang.org/book/title-page.html
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue