diff options
| author | Matthias Krüger <476013+matthiaskrgr@users.noreply.github.com> | 2025-07-18 04:27:51 +0200 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2025-07-18 04:27:51 +0200 |
| commit | accf61dd42548bd5ec61d43f246b3eb499e980dd (patch) | |
| tree | 31fad0f50ed48bd49c9d0b5451feeb9298ec856d /tests/codegen | |
| parent | b252014673d31f371757613a4ced13adfd6b304c (diff) | |
| parent | 9c8ab891876b37aac458a7461d904fe593856745 (diff) | |
| download | rust-accf61dd42548bd5ec61d43f246b3eb499e980dd.tar.gz rust-accf61dd42548bd5ec61d43f246b3eb499e980dd.zip | |
Rollup merge of #143293 - folkertdev:naked-function-kcfi, r=compiler-errors
fix `-Zsanitizer=kcfi` on `#[naked]` functions fixes https://github.com/rust-lang/rust/issues/143266 With `-Zsanitizer=kcfi`, indirect calls happen via generated intermediate shim that forwards the call. The generated shim preserves the attributes of the original, including `#[unsafe(naked)]`. The shim is not a naked function though, and violates its invariants (like having a body that consists of a single `naked_asm!` call). My fix here is to match on the `InstanceKind`, and only use `codegen_naked_asm` when the instance is not a `ReifyShim`. That does beg the question whether there are other `InstanceKind`s that could come up. As far as I can tell the answer is no: calling via `dyn` seems to work find, and `#[track_caller]` is disallowed in combination with `#[naked]`. r? codegen ````@rustbot```` label +A-naked cc ````@maurer```` ````@rcvalle````
Diffstat (limited to 'tests/codegen')
| -rw-r--r-- | tests/codegen/sanitizer/kcfi/naked-function.rs | 47 |
1 files changed, 47 insertions, 0 deletions
diff --git a/tests/codegen/sanitizer/kcfi/naked-function.rs b/tests/codegen/sanitizer/kcfi/naked-function.rs new file mode 100644 index 00000000000..2c8cdc919b8 --- /dev/null +++ b/tests/codegen/sanitizer/kcfi/naked-function.rs @@ -0,0 +1,47 @@ +//@ add-core-stubs +//@ 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 -Cno-prepopulate-passes -Copt-level=0 + +#![feature(no_core, lang_items)] +#![crate_type = "lib"] +#![no_core] + +extern crate minicore; +use minicore::*; + +struct Thing; +trait MyTrait { + #[unsafe(naked)] + extern "C" fn my_naked_function() { + // the real function is defined + // CHECK: .globl + // CHECK-SAME: my_naked_function + naked_asm!("ret") + } +} +impl MyTrait for Thing {} + +// the shim calls the real function +// CHECK-LABEL: define +// CHECK-SAME: my_naked_function +// CHECK-SAME: reify.shim.fnptr + +// CHECK-LABEL: main +#[unsafe(no_mangle)] +pub fn main() { + // Trick the compiler into generating an indirect call. + const F: extern "C" fn() = Thing::my_naked_function; + + // main calls the shim function + // CHECK: call void + // CHECK-SAME: my_naked_function + // CHECK-SAME: reify.shim.fnptr + (F)(); +} + +// CHECK: declare !kcfi_type +// CHECK-SAME: my_naked_function |
