Skip to content

Commit

Permalink
Allow disabling ASan instrumentation for globals
Browse files Browse the repository at this point in the history
AddressSanitizer adds instrumentation to global variables unless the
[`no_sanitize_address`](https://llvm.org/docs/LangRef.html#global-attributes)
attribute is set on them.

This commit extends the existing `#[no_sanitize(address)]` attribute to
set this; previously it only had the desired effect on functions.
  • Loading branch information
BertalanD committed Jul 8, 2024
1 parent 7fdefb8 commit b378189
Show file tree
Hide file tree
Showing 5 changed files with 43 additions and 0 deletions.
9 changes: 9 additions & 0 deletions compiler/rustc_codegen_llvm/src/base.rs
Original file line number Diff line number Diff line change
Expand Up @@ -150,6 +150,15 @@ pub fn set_link_section(llval: &Value, attrs: &CodegenFnAttrs) {
}
}

pub fn set_variable_sanitizer_attrs(llval: &Value, attrs: &CodegenFnAttrs) {
if attrs.no_sanitize.contains(SanitizerSet::ADDRESS) {
unsafe { llvm::LLVMRustSetNoSanitizeAddress(llval); }
}
if attrs.no_sanitize.contains(SanitizerSet::HWADDRESS) {
unsafe { llvm::LLVMRustSetNoSanitizeHWAddress(llval); }
}
}

pub fn linkage_to_llvm(linkage: Linkage) -> llvm::Linkage {
match linkage {
Linkage::External => llvm::Linkage::ExternalLinkage,
Expand Down
2 changes: 2 additions & 0 deletions compiler/rustc_codegen_llvm/src/consts.rs
Original file line number Diff line number Diff line change
Expand Up @@ -525,6 +525,8 @@ impl<'ll> CodegenCx<'ll, '_> {
base::set_link_section(g, attrs);
}

base::set_variable_sanitizer_attrs(g, attrs);

if attrs.flags.contains(CodegenFnAttrFlags::USED) {
// `USED` and `USED_LINKER` can't be used together.
assert!(!attrs.flags.contains(CodegenFnAttrFlags::USED_LINKER));
Expand Down
3 changes: 3 additions & 0 deletions compiler/rustc_codegen_llvm/src/llvm/ffi.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2440,4 +2440,7 @@ extern "C" {
callback: GetSymbolsCallback,
error_callback: GetSymbolsErrorCallback,
) -> *mut c_void;

pub fn LLVMRustSetNoSanitizeAddress(Global: &Value);
pub fn LLVMRustSetNoSanitizeHWAddress(Global: &Value);
}
19 changes: 19 additions & 0 deletions compiler/rustc_llvm/llvm-wrapper/RustWrapper.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2179,6 +2179,25 @@ extern "C" bool LLVMRustLLVMHasZstdCompressionForDebugSymbols() {
return llvm::compression::zstd::isAvailable();
}

extern "C" void LLVMRustSetNoSanitizeAddress(LLVMValueRef Global) {
GlobalValue &GV = *unwrap<GlobalValue>(Global);
GlobalValue::SanitizerMetadata MD;
if (GV.hasSanitizerMetadata())
MD = GV.getSanitizerMetadata();
MD.NoAddress = true;
MD.IsDynInit = false;
GV.setSanitizerMetadata(MD);
}

extern "C" void LLVMRustSetNoSanitizeHWAddress(LLVMValueRef Global) {
GlobalValue &GV = *unwrap<GlobalValue>(Global);
GlobalValue::SanitizerMetadata MD;
if (GV.hasSanitizerMetadata())
MD = GV.getSanitizerMetadata();
MD.NoHWAddress = true;
GV.setSanitizerMetadata(MD);
}

// Operations on composite constants.
// These are clones of LLVM api functions that will become available in future
// releases. They can be removed once Rust's minimum supported LLVM version
Expand Down
10 changes: 10 additions & 0 deletions tests/codegen/sanitizer/no-sanitize.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,16 @@
#![crate_type = "lib"]
#![feature(no_sanitize)]

// CHECK: @UNSANITIZED = constant{{.*}} no_sanitize_address
// CHECK-NOT: @__asan_global_UNSANITIZED
#[no_mangle]
#[no_sanitize(address)]
pub static UNSANITIZED: u32 = 0;

// CHECK: @__asan_global_SANITIZED
#[no_mangle]
pub static SANITIZED: u32 = 0;

// CHECK-LABEL: ; no_sanitize::unsanitized
// CHECK-NEXT: ; Function Attrs:
// CHECK-NOT: sanitize_address
Expand Down

0 comments on commit b378189

Please sign in to comment.