Add missing module flags for CFI and KCFI sanitizers
Set the cfi-normalize-integers and kcfi-offset module flags when Control-Flow Integrity sanitizers are used, so functions generated by the LLVM backend use the same CFI/KCFI options as rustc. cfi-normalize-integers tells LLVM to also use integer normalization for generated functions when -Zsanitizer-cfi-normalize-integers is used. kcfi-offset specifies the number of prefix nops between the KCFI type hash and the function entry when -Z patchable-function-entry is used. Note that LLVM assumes all indirectly callable functions use the same number of prefix NOPs with -Zsanitizer=kcfi.
This commit is contained in:
parent
6b678c57b6
commit
40f1d9d154
@ -11,6 +11,7 @@
|
||||
use rustc_data_structures::fx::FxHashMap;
|
||||
use rustc_data_structures::small_c_str::SmallCStr;
|
||||
use rustc_hir::def_id::DefId;
|
||||
use rustc_middle::middle::codegen_fn_attrs::PatchableFunctionEntry;
|
||||
use rustc_middle::mir::mono::CodegenUnit;
|
||||
use rustc_middle::ty::layout::{
|
||||
FnAbiError, FnAbiOfHelpers, FnAbiRequest, HasParamEnv, LayoutError, LayoutOfHelpers,
|
||||
@ -226,6 +227,20 @@ pub unsafe fn create_module<'ll>(
|
||||
}
|
||||
}
|
||||
|
||||
// If we're normalizing integers with CFI, ensure LLVM generated functions do the same.
|
||||
// See https://github.com/llvm/llvm-project/pull/104826
|
||||
if sess.is_sanitizer_cfi_normalize_integers_enabled() {
|
||||
let cfi_normalize_integers = c"cfi-normalize-integers".as_ptr().cast();
|
||||
unsafe {
|
||||
llvm::LLVMRustAddModuleFlagU32(
|
||||
llmod,
|
||||
llvm::LLVMModFlagBehavior::Override,
|
||||
cfi_normalize_integers,
|
||||
1,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
// Enable LTO unit splitting if specified or if CFI is enabled. (See https://reviews.llvm.org/D53891.)
|
||||
if sess.is_split_lto_unit_enabled() || sess.is_sanitizer_cfi_enabled() {
|
||||
let enable_split_lto_unit = c"EnableSplitLTOUnit".as_ptr();
|
||||
@ -245,6 +260,22 @@ pub unsafe fn create_module<'ll>(
|
||||
unsafe {
|
||||
llvm::LLVMRustAddModuleFlagU32(llmod, llvm::LLVMModFlagBehavior::Override, kcfi, 1);
|
||||
}
|
||||
|
||||
// Add "kcfi-offset" module flag with -Z patchable-function-entry (See
|
||||
// https://reviews.llvm.org/D141172).
|
||||
let pfe =
|
||||
PatchableFunctionEntry::from_config(sess.opts.unstable_opts.patchable_function_entry);
|
||||
if pfe.prefix() > 0 {
|
||||
let kcfi_offset = c"kcfi-offset".as_ptr().cast();
|
||||
unsafe {
|
||||
llvm::LLVMRustAddModuleFlagU32(
|
||||
llmod,
|
||||
llvm::LLVMModFlagBehavior::Override,
|
||||
kcfi_offset,
|
||||
pfe.prefix().into(),
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Control Flow Guard is currently only supported by the MSVC linker on Windows.
|
||||
|
@ -0,0 +1,10 @@
|
||||
// Verifies that "cfi-normalize-integers" module flag is added.
|
||||
//
|
||||
//@ needs-sanitizer-cfi
|
||||
//@ compile-flags: -Clto -Ctarget-feature=-crt-static -Zsanitizer=cfi -Zsanitizer-cfi-normalize-integers
|
||||
|
||||
#![crate_type = "lib"]
|
||||
|
||||
pub fn foo() {}
|
||||
|
||||
// CHECK: !{{[0-9]+}} = !{i32 4, !"cfi-normalize-integers", i32 1}
|
@ -0,0 +1,21 @@
|
||||
// Verifies that "cfi-normalize-integers" module flag is added.
|
||||
//
|
||||
//@ revisions: aarch64 x86_64
|
||||
//@ [aarch64] compile-flags: --target aarch64-unknown-none
|
||||
//@ [aarch64] needs-llvm-components: aarch64
|
||||
//@ [x86_64] compile-flags: --target x86_64-unknown-none
|
||||
//@ [x86_64] needs-llvm-components: x86
|
||||
//@ compile-flags: -Ctarget-feature=-crt-static -Zsanitizer=kcfi -Zsanitizer-cfi-normalize-integers
|
||||
|
||||
#![feature(no_core, lang_items)]
|
||||
#![crate_type = "lib"]
|
||||
#![no_core]
|
||||
|
||||
#[lang = "sized"]
|
||||
trait Sized {}
|
||||
#[lang = "copy"]
|
||||
trait Copy {}
|
||||
|
||||
pub fn foo() {}
|
||||
|
||||
// CHECK: !{{[0-9]+}} = !{i32 4, !"cfi-normalize-integers", i32 1}
|
21
tests/codegen/sanitizer/kcfi/add-kcfi-offset-flag.rs
Normal file
21
tests/codegen/sanitizer/kcfi/add-kcfi-offset-flag.rs
Normal file
@ -0,0 +1,21 @@
|
||||
// Verifies that "kcfi-offset" module flag is added.
|
||||
//
|
||||
//@ revisions: aarch64 x86_64
|
||||
//@ [aarch64] compile-flags: --target aarch64-unknown-none
|
||||
//@ [aarch64] needs-llvm-components: aarch64
|
||||
//@ [x86_64] compile-flags: --target x86_64-unknown-none
|
||||
//@ [x86_64] needs-llvm-components: x86
|
||||
//@ compile-flags: -Ctarget-feature=-crt-static -Zsanitizer=kcfi -Z patchable-function-entry=4,3
|
||||
|
||||
#![feature(no_core, lang_items, patchable_function_entry)]
|
||||
#![crate_type = "lib"]
|
||||
#![no_core]
|
||||
|
||||
#[lang = "sized"]
|
||||
trait Sized {}
|
||||
#[lang = "copy"]
|
||||
trait Copy {}
|
||||
|
||||
pub fn foo() {}
|
||||
|
||||
// CHECK: !{{[0-9]+}} = !{i32 4, !"kcfi-offset", i32 3}
|
Loading…
Reference in New Issue
Block a user