1
Fork 0

Rollup merge of #105109 - rcvalle:rust-kcfi, r=bjorn3

Add LLVM KCFI support to the Rust compiler

This PR adds LLVM Kernel Control Flow Integrity (KCFI) support to the Rust compiler. It initially provides forward-edge control flow protection for operating systems kernels for Rust-compiled code only by aggregating function pointers in groups identified by their return and parameter types. (See llvm/llvm-project@cff5bef.)

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 identifying C char and integer type uses at the time types are encoded (see Type metadata in the design document in the tracking issue #89653).

LLVM KCFI can be enabled with -Zsanitizer=kcfi.

Thank you again, `@bjorn3,` `@eddyb,` `@nagisa,` and `@ojeda,` for all the help!
This commit is contained in:
Matthias Krüger 2022-12-10 09:24:43 +01:00 committed by GitHub
commit 947fe7e341
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
27 changed files with 261 additions and 28 deletions

View file

@ -368,7 +368,7 @@ mod desc {
pub const parse_opt_panic_strategy: &str = parse_panic_strategy;
pub const parse_oom_strategy: &str = "either `panic` or `abort`";
pub const parse_relro_level: &str = "one of: `full`, `partial`, or `off`";
pub const parse_sanitizers: &str = "comma separated list of sanitizers: `address`, `cfi`, `hwaddress`, `leak`, `memory`, `memtag`, `shadow-call-stack`, or `thread`";
pub const parse_sanitizers: &str = "comma separated list of sanitizers: `address`, `cfi`, `hwaddress`, `kcfi`, `leak`, `memory`, `memtag`, `shadow-call-stack`, 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`";
@ -675,6 +675,7 @@ mod parse {
*slot |= match s {
"address" => SanitizerSet::ADDRESS,
"cfi" => SanitizerSet::CFI,
"kcfi" => SanitizerSet::KCFI,
"leak" => SanitizerSet::LEAK,
"memory" => SanitizerSet::MEMORY,
"memtag" => SanitizerSet::MEMTAG,

View file

@ -686,6 +686,10 @@ impl Session {
self.opts.unstable_opts.sanitizer.contains(SanitizerSet::CFI)
}
pub fn is_sanitizer_kcfi_enabled(&self) -> bool {
self.opts.unstable_opts.sanitizer.contains(SanitizerSet::KCFI)
}
/// Check whether this compile session and crate type use static crt.
pub fn crt_static(&self, crate_type: Option<CrateType>) -> bool {
if !self.target.crt_static_respected {
@ -1544,6 +1548,14 @@ fn validate_commandline_args_with_session_available(sess: &Session) {
}
}
// LLVM CFI and KCFI are mutually exclusive
if sess.is_sanitizer_cfi_enabled() && sess.is_sanitizer_kcfi_enabled() {
sess.emit_err(CannotMixAndMatchSanitizers {
first: "cfi".to_string(),
second: "kcfi".to_string(),
});
}
if sess.opts.unstable_opts.stack_protector != StackProtector::None {
if !sess.target.options.supports_stack_protector {
sess.emit_warning(StackProtectorNotSupportedForTarget {