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 9df55b1

Browse files
committedMar 11, 2025
KCFI: Add KCFI arity indicator support
Adds KCFI KCFI arity indicator support to the Rust compiler (see llvm/llvm-project#117121 and https://lore.kernel.org/lkml/CANiq72=3ghFxy8E=AU9p+0imFxKr5iU3sd0hVUXed5BA+KjdNQ@mail.gmail.com/).
1 parent ebf0cf7 commit 9df55b1

File tree

9 files changed

+54
-0
lines changed

9 files changed

+54
-0
lines changed
 

‎compiler/rustc_codegen_llvm/src/context.rs

+6
Original file line numberDiff line numberDiff line change
@@ -328,6 +328,12 @@ pub(crate) unsafe fn create_module<'ll>(
328328
}
329329
}
330330

331+
// Add "kcfi-arity" module flag if KCFI arity indicator is enabled. (See
332+
// https://github.com/llvm/llvm-project/pull/117121.)
333+
if sess.is_sanitizer_kcfi_arity_enabled() && sess.is_sanitizer_kcfi_enabled() {
334+
llvm::add_module_flag_u32(llmod, llvm::ModuleFlagMergeBehavior::Override, "kcfi-arity", 1);
335+
}
336+
331337
// Control Flow Guard is currently only supported by MSVC and LLVM on Windows.
332338
if sess.target.is_like_msvc
333339
|| (sess.target.options.os == "windows"

‎compiler/rustc_interface/src/tests.rs

+1
Original file line numberDiff line numberDiff line change
@@ -852,6 +852,7 @@ fn test_unstable_options_tracking_hash() {
852852
tracked!(sanitizer_cfi_generalize_pointers, Some(true));
853853
tracked!(sanitizer_cfi_normalize_integers, Some(true));
854854
tracked!(sanitizer_dataflow_abilist, vec![String::from("/rustc/abc")]);
855+
tracked!(sanitizer_kcfi_arity, None);
855856
tracked!(sanitizer_memory_track_origins, 2);
856857
tracked!(sanitizer_recover, SanitizerSet::ADDRESS);
857858
tracked!(saturating_float_casts, Some(true));

‎compiler/rustc_session/messages.ftl

+2
Original file line numberDiff line numberDiff line change
@@ -94,6 +94,8 @@ session_sanitizer_cfi_requires_lto = `-Zsanitizer=cfi` requires `-Clto` or `-Cli
9494
9595
session_sanitizer_cfi_requires_single_codegen_unit = `-Zsanitizer=cfi` with `-Clto` requires `-Ccodegen-units=1`
9696
97+
session_sanitizer_kcfi_arity_requires_kcfi = `-Zsanitizer-kcfi-arity` requires `-Zsanitizer=kcfi`
98+
9799
session_sanitizer_kcfi_requires_panic_abort = `-Z sanitizer=kcfi` requires `-C panic=abort`
98100
99101
session_sanitizer_not_supported = {$us} sanitizer is not supported for this target

‎compiler/rustc_session/src/errors.rs

+4
Original file line numberDiff line numberDiff line change
@@ -147,6 +147,10 @@ pub(crate) struct SanitizerCfiGeneralizePointersRequiresCfi;
147147
#[diag(session_sanitizer_cfi_normalize_integers_requires_cfi)]
148148
pub(crate) struct SanitizerCfiNormalizeIntegersRequiresCfi;
149149

150+
#[derive(Diagnostic)]
151+
#[diag(session_sanitizer_kcfi_arity_requires_kcfi)]
152+
pub(crate) struct SanitizerKcfiArityRequiresKcfi;
153+
150154
#[derive(Diagnostic)]
151155
#[diag(session_sanitizer_kcfi_requires_panic_abort)]
152156
pub(crate) struct SanitizerKcfiRequiresPanicAbort;

‎compiler/rustc_session/src/options.rs

+2
Original file line numberDiff line numberDiff line change
@@ -2433,6 +2433,8 @@ written to standard error output)"),
24332433
"enable normalizing integer types (default: no)"),
24342434
sanitizer_dataflow_abilist: Vec<String> = (Vec::new(), parse_comma_list, [TRACKED],
24352435
"additional ABI list files that control how shadow parameters are passed (comma separated)"),
2436+
sanitizer_kcfi_arity: Option<bool> = (None, parse_opt_bool, [TRACKED],
2437+
"enable KCFI arity indicator (default: no)"),
24362438
sanitizer_memory_track_origins: usize = (0, parse_sanitizer_memory_track_origins, [TRACKED],
24372439
"enable origins tracking in MemorySanitizer"),
24382440
sanitizer_recover: SanitizerSet = (SanitizerSet::empty(), parse_sanitizers, [TRACKED],

‎compiler/rustc_session/src/session.rs

+9
Original file line numberDiff line numberDiff line change
@@ -382,6 +382,10 @@ impl Session {
382382
self.opts.unstable_opts.sanitizer_cfi_normalize_integers == Some(true)
383383
}
384384

385+
pub fn is_sanitizer_kcfi_arity_enabled(&self) -> bool {
386+
self.opts.unstable_opts.sanitizer_kcfi_arity == Some(true)
387+
}
388+
385389
pub fn is_sanitizer_kcfi_enabled(&self) -> bool {
386390
self.opts.unstable_opts.sanitizer.contains(SanitizerSet::KCFI)
387391
}
@@ -1204,6 +1208,11 @@ fn validate_commandline_args_with_session_available(sess: &Session) {
12041208
}
12051209
}
12061210

1211+
// KCFI arity indicator requires KCFI.
1212+
if sess.is_sanitizer_kcfi_arity_enabled() && !sess.is_sanitizer_kcfi_enabled() {
1213+
sess.dcx().emit_err(errors::SanitizerKcfiArityRequiresKcfi);
1214+
}
1215+
12071216
// LLVM CFI pointer generalization requires CFI or KCFI.
12081217
if sess.is_sanitizer_cfi_generalize_pointers_enabled() {
12091218
if !(sess.is_sanitizer_cfi_enabled() || sess.is_sanitizer_kcfi_enabled()) {
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
// Verifies that "kcfi-arity" module flag is added.
2+
//
3+
//@ add-core-stubs
4+
//@ revisions: x86_64
5+
//@ [x86_64] compile-flags: --target x86_64-unknown-none
6+
//@ [x86_64] needs-llvm-components: x86
7+
//@ compile-flags: -Ctarget-feature=-crt-static -Zsanitizer=kcfi -Zsanitizer-kcfi-arity
8+
9+
#![feature(no_core, lang_items)]
10+
#![crate_type = "lib"]
11+
#![no_core]
12+
13+
extern crate minicore;
14+
use minicore::*;
15+
16+
pub fn foo() {}
17+
18+
// CHECK: !{{[0-9]+}} = !{i32 4, !"kcfi-arity", i32 1}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
// Verifies that `-Zsanitizer-kcfi-arity` requires `-Zsanitizer=kcfi`.
2+
//
3+
//@ needs-sanitizer-kcfi
4+
//@ compile-flags: -Cno-prepopulate-passes -Ctarget-feature=-crt-static -Zsanitizer-kcfi-arity
5+
6+
#![feature(no_core)]
7+
#![no_core]
8+
#![no_main]
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
error: `-Zsanitizer-kcfi-arity` requires `-Zsanitizer=kcfi`
2+
3+
error: aborting due to 1 previous error
4+

0 commit comments

Comments
 (0)
Failed to load comments.