Skip to content
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.

Commit a0428cb

Browse files
authoredAug 22, 2024
Rollup merge of rust-lang#129373 - samitolvanen:cfi-module-flags, r=compiler-errors
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.
2 parents 114d6b0 + 40f1d9d commit a0428cb

File tree

4 files changed

+83
-0
lines changed

4 files changed

+83
-0
lines changed
 

‎compiler/rustc_codegen_llvm/src/context.rs

+31
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ use rustc_data_structures::base_n::{ToBaseN, ALPHANUMERIC_ONLY};
1111
use rustc_data_structures::fx::FxHashMap;
1212
use rustc_data_structures::small_c_str::SmallCStr;
1313
use rustc_hir::def_id::DefId;
14+
use rustc_middle::middle::codegen_fn_attrs::PatchableFunctionEntry;
1415
use rustc_middle::mir::mono::CodegenUnit;
1516
use rustc_middle::ty::layout::{
1617
FnAbiError, FnAbiOfHelpers, FnAbiRequest, HasParamEnv, LayoutError, LayoutOfHelpers,
@@ -226,6 +227,20 @@ pub unsafe fn create_module<'ll>(
226227
}
227228
}
228229

230+
// If we're normalizing integers with CFI, ensure LLVM generated functions do the same.
231+
// See https://github.com/llvm/llvm-project/pull/104826
232+
if sess.is_sanitizer_cfi_normalize_integers_enabled() {
233+
let cfi_normalize_integers = c"cfi-normalize-integers".as_ptr().cast();
234+
unsafe {
235+
llvm::LLVMRustAddModuleFlagU32(
236+
llmod,
237+
llvm::LLVMModFlagBehavior::Override,
238+
cfi_normalize_integers,
239+
1,
240+
);
241+
}
242+
}
243+
229244
// Enable LTO unit splitting if specified or if CFI is enabled. (See https://reviews.llvm.org/D53891.)
230245
if sess.is_split_lto_unit_enabled() || sess.is_sanitizer_cfi_enabled() {
231246
let enable_split_lto_unit = c"EnableSplitLTOUnit".as_ptr();
@@ -245,6 +260,22 @@ pub unsafe fn create_module<'ll>(
245260
unsafe {
246261
llvm::LLVMRustAddModuleFlagU32(llmod, llvm::LLVMModFlagBehavior::Override, kcfi, 1);
247262
}
263+
264+
// Add "kcfi-offset" module flag with -Z patchable-function-entry (See
265+
// https://reviews.llvm.org/D141172).
266+
let pfe =
267+
PatchableFunctionEntry::from_config(sess.opts.unstable_opts.patchable_function_entry);
268+
if pfe.prefix() > 0 {
269+
let kcfi_offset = c"kcfi-offset".as_ptr().cast();
270+
unsafe {
271+
llvm::LLVMRustAddModuleFlagU32(
272+
llmod,
273+
llvm::LLVMModFlagBehavior::Override,
274+
kcfi_offset,
275+
pfe.prefix().into(),
276+
);
277+
}
278+
}
248279
}
249280

250281
// Control Flow Guard is currently only supported by the MSVC linker on Windows.
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
// Verifies that "cfi-normalize-integers" module flag is added.
2+
//
3+
//@ needs-sanitizer-cfi
4+
//@ compile-flags: -Clto -Ctarget-feature=-crt-static -Zsanitizer=cfi -Zsanitizer-cfi-normalize-integers
5+
6+
#![crate_type = "lib"]
7+
8+
pub fn foo() {}
9+
10+
// CHECK: !{{[0-9]+}} = !{i32 4, !"cfi-normalize-integers", i32 1}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
// Verifies that "cfi-normalize-integers" module flag is added.
2+
//
3+
//@ revisions: aarch64 x86_64
4+
//@ [aarch64] compile-flags: --target aarch64-unknown-none
5+
//@ [aarch64] needs-llvm-components: aarch64
6+
//@ [x86_64] compile-flags: --target x86_64-unknown-none
7+
//@ [x86_64] needs-llvm-components: x86
8+
//@ compile-flags: -Ctarget-feature=-crt-static -Zsanitizer=kcfi -Zsanitizer-cfi-normalize-integers
9+
10+
#![feature(no_core, lang_items)]
11+
#![crate_type = "lib"]
12+
#![no_core]
13+
14+
#[lang = "sized"]
15+
trait Sized {}
16+
#[lang = "copy"]
17+
trait Copy {}
18+
19+
pub fn foo() {}
20+
21+
// CHECK: !{{[0-9]+}} = !{i32 4, !"cfi-normalize-integers", i32 1}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
// Verifies that "kcfi-offset" module flag is added.
2+
//
3+
//@ revisions: aarch64 x86_64
4+
//@ [aarch64] compile-flags: --target aarch64-unknown-none
5+
//@ [aarch64] needs-llvm-components: aarch64
6+
//@ [x86_64] compile-flags: --target x86_64-unknown-none
7+
//@ [x86_64] needs-llvm-components: x86
8+
//@ compile-flags: -Ctarget-feature=-crt-static -Zsanitizer=kcfi -Z patchable-function-entry=4,3
9+
10+
#![feature(no_core, lang_items, patchable_function_entry)]
11+
#![crate_type = "lib"]
12+
#![no_core]
13+
14+
#[lang = "sized"]
15+
trait Sized {}
16+
#[lang = "copy"]
17+
trait Copy {}
18+
19+
pub fn foo() {}
20+
21+
// CHECK: !{{[0-9]+}} = !{i32 4, !"kcfi-offset", i32 3}

0 commit comments

Comments
 (0)
Failed to load comments.