From 54ebb9d4897c2f372e3b20f833c2ea4eaf656a0e Mon Sep 17 00:00:00 2001 From: Nikita Popov Date: Mon, 2 Sep 2024 15:45:06 +0200 Subject: [PATCH] Do not request sanitizers for naked functions Naked functions can only contain inline asm, so any instrumentation inserted by sanitizers is illegal. Don't request it. Fixes https://github.com/rust-lang/rust/issues/129224. --- compiler/rustc_codegen_llvm/src/attributes.rs | 46 ++++++++++--------- tests/codegen/naked-asan.rs | 22 +++++++++ 2 files changed, 47 insertions(+), 21 deletions(-) create mode 100644 tests/codegen/naked-asan.rs diff --git a/compiler/rustc_codegen_llvm/src/attributes.rs b/compiler/rustc_codegen_llvm/src/attributes.rs index 92a857c2adcf4..9d4497d73a8ae 100644 --- a/compiler/rustc_codegen_llvm/src/attributes.rs +++ b/compiler/rustc_codegen_llvm/src/attributes.rs @@ -411,26 +411,31 @@ pub(crate) fn llfn_attrs_from_instance<'ll, 'tcx>( // the string "false". Now it is disabled by absence of the attribute. to_add.push(llvm::CreateAttrStringValue(cx.llcx, "branch-target-enforcement", "false")); } - } else if llvm_util::get_version() >= (19, 0, 0) { - // For non-naked functions, set branch protection attributes on aarch64. - if let Some(BranchProtection { bti, pac_ret }) = - cx.sess().opts.unstable_opts.branch_protection - { - assert!(cx.sess().target.arch == "aarch64"); - if bti { - to_add.push(llvm::CreateAttrString(cx.llcx, "branch-target-enforcement")); - } - if let Some(PacRet { leaf, key }) = pac_ret { - to_add.push(llvm::CreateAttrStringValue( - cx.llcx, - "sign-return-address", - if leaf { "all" } else { "non-leaf" }, - )); - to_add.push(llvm::CreateAttrStringValue( - cx.llcx, - "sign-return-address-key", - if key == PAuthKey::A { "a_key" } else { "b_key" }, - )); + } else { + // Do not set sanitizer attributes for naked functions. + to_add.extend(sanitize_attrs(cx, codegen_fn_attrs.no_sanitize)); + + if llvm_util::get_version() >= (19, 0, 0) { + // For non-naked functions, set branch protection attributes on aarch64. + if let Some(BranchProtection { bti, pac_ret }) = + cx.sess().opts.unstable_opts.branch_protection + { + assert!(cx.sess().target.arch == "aarch64"); + if bti { + to_add.push(llvm::CreateAttrString(cx.llcx, "branch-target-enforcement")); + } + if let Some(PacRet { leaf, key }) = pac_ret { + to_add.push(llvm::CreateAttrStringValue( + cx.llcx, + "sign-return-address", + if leaf { "all" } else { "non-leaf" }, + )); + to_add.push(llvm::CreateAttrStringValue( + cx.llcx, + "sign-return-address-key", + if key == PAuthKey::A { "a_key" } else { "b_key" }, + )); + } } } } @@ -485,7 +490,6 @@ pub(crate) fn llfn_attrs_from_instance<'ll, 'tcx>( if let Some(backchain) = backchain_attr(cx) { to_add.push(backchain); } - to_add.extend(sanitize_attrs(cx, codegen_fn_attrs.no_sanitize)); to_add.extend(patchable_function_entry_attrs(cx, codegen_fn_attrs.patchable_function_entry)); // Always annotate functions with the target-cpu they are compiled for. diff --git a/tests/codegen/naked-asan.rs b/tests/codegen/naked-asan.rs new file mode 100644 index 0000000000000..a45b95780f793 --- /dev/null +++ b/tests/codegen/naked-asan.rs @@ -0,0 +1,22 @@ +// Make sure we do not request sanitizers for naked functions. + +//@ only-x86_64 +//@ needs-sanitizer-address +//@ compile-flags: -Zsanitizer=address -Ctarget-feature=-crt-static + +#![crate_type = "lib"] +#![no_std] +#![feature(abi_x86_interrupt, naked_functions)] + +// CHECK: define x86_intrcc void @page_fault_handler(ptr {{.*}}%0, i64 {{.*}}%1){{.*}}#[[ATTRS:[0-9]+]] { +// CHECK-NOT: memcpy +#[naked] +#[no_mangle] +pub extern "x86-interrupt" fn page_fault_handler(_: u64, _: u64) { + unsafe { + core::arch::asm!("ud2", options(noreturn)); + } +} + +// CHECK: #[[ATTRS]] = +// CHECK-NOT: sanitize_address