Skip to content

Commit 9d17424

Browse files
committed
Allow disabling ASan instrumentation for globals
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.
1 parent cb12b52 commit 9d17424

File tree

5 files changed

+43
-0
lines changed

5 files changed

+43
-0
lines changed

compiler/rustc_codegen_llvm/src/base.rs

+9
Original file line numberDiff line numberDiff line change
@@ -150,6 +150,15 @@ pub fn set_link_section(llval: &Value, attrs: &CodegenFnAttrs) {
150150
}
151151
}
152152

153+
pub fn set_variable_sanitizer_attrs(llval: &Value, attrs: &CodegenFnAttrs) {
154+
if attrs.no_sanitize.contains(SanitizerSet::ADDRESS) {
155+
unsafe { llvm::LLVMRustSetNoSanitizeAddress(llval) };
156+
}
157+
if attrs.no_sanitize.contains(SanitizerSet::HWADDRESS) {
158+
unsafe { llvm::LLVMRustSetNoSanitizeHWAddress(llval) };
159+
}
160+
}
161+
153162
pub fn linkage_to_llvm(linkage: Linkage) -> llvm::Linkage {
154163
match linkage {
155164
Linkage::External => llvm::Linkage::ExternalLinkage,

compiler/rustc_codegen_llvm/src/consts.rs

+2
Original file line numberDiff line numberDiff line change
@@ -525,6 +525,8 @@ impl<'ll> CodegenCx<'ll, '_> {
525525
base::set_link_section(g, attrs);
526526
}
527527

528+
base::set_variable_sanitizer_attrs(g, attrs);
529+
528530
if attrs.flags.contains(CodegenFnAttrFlags::USED) {
529531
// `USED` and `USED_LINKER` can't be used together.
530532
assert!(!attrs.flags.contains(CodegenFnAttrFlags::USED_LINKER));

compiler/rustc_codegen_llvm/src/llvm/ffi.rs

+3
Original file line numberDiff line numberDiff line change
@@ -2444,4 +2444,7 @@ extern "C" {
24442444
pub fn LLVMRustIs64BitSymbolicFile(buf_ptr: *const u8, buf_len: usize) -> bool;
24452445

24462446
pub fn LLVMRustIsECObject(buf_ptr: *const u8, buf_len: usize) -> bool;
2447+
2448+
pub fn LLVMRustSetNoSanitizeAddress(Global: &Value);
2449+
pub fn LLVMRustSetNoSanitizeHWAddress(Global: &Value);
24472450
}

compiler/rustc_llvm/llvm-wrapper/RustWrapper.cpp

+19
Original file line numberDiff line numberDiff line change
@@ -2174,6 +2174,25 @@ extern "C" bool LLVMRustLLVMHasZstdCompressionForDebugSymbols() {
21742174
return llvm::compression::zstd::isAvailable();
21752175
}
21762176

2177+
extern "C" void LLVMRustSetNoSanitizeAddress(LLVMValueRef Global) {
2178+
GlobalValue &GV = *unwrap<GlobalValue>(Global);
2179+
GlobalValue::SanitizerMetadata MD;
2180+
if (GV.hasSanitizerMetadata())
2181+
MD = GV.getSanitizerMetadata();
2182+
MD.NoAddress = true;
2183+
MD.IsDynInit = false;
2184+
GV.setSanitizerMetadata(MD);
2185+
}
2186+
2187+
extern "C" void LLVMRustSetNoSanitizeHWAddress(LLVMValueRef Global) {
2188+
GlobalValue &GV = *unwrap<GlobalValue>(Global);
2189+
GlobalValue::SanitizerMetadata MD;
2190+
if (GV.hasSanitizerMetadata())
2191+
MD = GV.getSanitizerMetadata();
2192+
MD.NoHWAddress = true;
2193+
GV.setSanitizerMetadata(MD);
2194+
}
2195+
21772196
// Operations on composite constants.
21782197
// These are clones of LLVM api functions that will become available in future
21792198
// releases. They can be removed once Rust's minimum supported LLVM version

tests/codegen/sanitizer/no-sanitize.rs

+10
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,16 @@
77
#![crate_type = "lib"]
88
#![feature(no_sanitize)]
99

10+
// CHECK: @UNSANITIZED = constant{{.*}} no_sanitize_address
11+
// CHECK-NOT: @__asan_global_UNSANITIZED
12+
#[no_mangle]
13+
#[no_sanitize(address)]
14+
pub static UNSANITIZED: u32 = 0;
15+
16+
// CHECK: @__asan_global_SANITIZED
17+
#[no_mangle]
18+
pub static SANITIZED: u32 = 0;
19+
1020
// CHECK-LABEL: ; no_sanitize::unsanitized
1121
// CHECK-NEXT: ; Function Attrs:
1222
// CHECK-NOT: sanitize_address

0 commit comments

Comments
 (0)