about summary refs log tree commit diff
path: root/compiler/rustc_session/src
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2021-10-27 09:19:42 +0000
committerbors <bors@rust-lang.org>2021-10-27 09:19:42 +0000
commita8f6e614f86be429b5862f30e023063f619aeed2 (patch)
tree329266e75828737d5cd8f66a7b27bb02379f9308 /compiler/rustc_session/src
parent47aeac648ed56095688c1c20972c9b72bd0da7ce (diff)
parentc5708caf6a858b76b5519f81d2061ef85d9976b6 (diff)
downloadrust-a8f6e614f86be429b5862f30e023063f619aeed2.tar.gz
rust-a8f6e614f86be429b5862f30e023063f619aeed2.zip
Auto merge of #89652 - rcvalle:rust-cfi, r=nagisa
Add LLVM CFI support to the Rust compiler

This PR adds LLVM Control Flow Integrity (CFI) support to the Rust compiler. It initially provides forward-edge control flow protection for Rust-compiled code only by aggregating function pointers in groups identified by their number of arguments.

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 virtual address space) will be provided in later work as part of this project by defining and using compatible type identifiers (see Type metadata in the design document in the tracking issue #89653).

LLVM CFI can be enabled with -Zsanitizer=cfi and requires LTO (i.e., -Clto).

Thank you, `@eddyb` and `@pcc,` for all the help!
Diffstat (limited to 'compiler/rustc_session/src')
-rw-r--r--compiler/rustc_session/src/options.rs4
-rw-r--r--compiler/rustc_session/src/session.rs13
2 files changed, 15 insertions, 2 deletions
diff --git a/compiler/rustc_session/src/options.rs b/compiler/rustc_session/src/options.rs
index 3ff91c0553a..e894e46a301 100644
--- a/compiler/rustc_session/src/options.rs
+++ b/compiler/rustc_session/src/options.rs
@@ -351,8 +351,7 @@ mod desc {
     pub const parse_panic_strategy: &str = "either `unwind` or `abort`";
     pub const parse_opt_panic_strategy: &str = parse_panic_strategy;
     pub const parse_relro_level: &str = "one of: `full`, `partial`, or `off`";
-    pub const parse_sanitizers: &str =
-        "comma separated list of sanitizers: `address`, `hwaddress`, `leak`, `memory` or `thread`";
+    pub const parse_sanitizers: &str = "comma separated list of sanitizers: `address`, `cfi`, `hwaddress`, `leak`, `memory` or `thread`";
     pub const parse_sanitizer_memory_track_origins: &str = "0, 1, or 2";
     pub const parse_cfguard: &str =
         "either a boolean (`yes`, `no`, `on`, `off`, etc), `checks`, or `nochecks`";
@@ -605,6 +604,7 @@ mod parse {
             for s in v.split(',') {
                 *slot |= match s {
                     "address" => SanitizerSet::ADDRESS,
+                    "cfi" => SanitizerSet::CFI,
                     "leak" => SanitizerSet::LEAK,
                     "memory" => SanitizerSet::MEMORY,
                     "thread" => SanitizerSet::THREAD,
diff --git a/compiler/rustc_session/src/session.rs b/compiler/rustc_session/src/session.rs
index b6ba6cc1dd6..0f6a3ddccba 100644
--- a/compiler/rustc_session/src/session.rs
+++ b/compiler/rustc_session/src/session.rs
@@ -672,6 +672,9 @@ impl Session {
     pub fn is_nightly_build(&self) -> bool {
         self.opts.unstable_features.is_nightly_build()
     }
+    pub fn is_sanitizer_cfi_enabled(&self) -> bool {
+        self.opts.debugging_opts.sanitizer.contains(SanitizerSet::CFI)
+    }
     pub fn overflow_checks(&self) -> bool {
         self.opts
             .cg
@@ -1398,6 +1401,16 @@ fn validate_commandline_args_with_session_available(sess: &Session) {
                                 disable it using `-C target-feature=-crt-static`",
         );
     }
+
+    // LLVM CFI requires LTO.
+    if sess.is_sanitizer_cfi_enabled() {
+        if sess.opts.cg.lto == config::LtoCli::Unspecified
+            || sess.opts.cg.lto == config::LtoCli::No
+            || sess.opts.cg.lto == config::LtoCli::Thin
+        {
+            sess.err("`-Zsanitizer=cfi` requires `-Clto`");
+        }
+    }
 }
 
 /// Holds data on the current incremental compilation session, if there is one.