Skip to content

Commit b378189

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 7fdefb8 commit b378189

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
@@ -2440,4 +2440,7 @@ extern "C" {
24402440
callback: GetSymbolsCallback,
24412441
error_callback: GetSymbolsErrorCallback,
24422442
) -> *mut c_void;
2443+
2444+
pub fn LLVMRustSetNoSanitizeAddress(Global: &Value);
2445+
pub fn LLVMRustSetNoSanitizeHWAddress(Global: &Value);
24432446
}

compiler/rustc_llvm/llvm-wrapper/RustWrapper.cpp

+19
Original file line numberDiff line numberDiff line change
@@ -2179,6 +2179,25 @@ extern "C" bool LLVMRustLLVMHasZstdCompressionForDebugSymbols() {
21792179
return llvm::compression::zstd::isAvailable();
21802180
}
21812181

2182+
extern "C" void LLVMRustSetNoSanitizeAddress(LLVMValueRef Global) {
2183+
GlobalValue &GV = *unwrap<GlobalValue>(Global);
2184+
GlobalValue::SanitizerMetadata MD;
2185+
if (GV.hasSanitizerMetadata())
2186+
MD = GV.getSanitizerMetadata();
2187+
MD.NoAddress = true;
2188+
MD.IsDynInit = false;
2189+
GV.setSanitizerMetadata(MD);
2190+
}
2191+
2192+
extern "C" void LLVMRustSetNoSanitizeHWAddress(LLVMValueRef Global) {
2193+
GlobalValue &GV = *unwrap<GlobalValue>(Global);
2194+
GlobalValue::SanitizerMetadata MD;
2195+
if (GV.hasSanitizerMetadata())
2196+
MD = GV.getSanitizerMetadata();
2197+
MD.NoHWAddress = true;
2198+
GV.setSanitizerMetadata(MD);
2199+
}
2200+
21822201
// Operations on composite constants.
21832202
// These are clones of LLVM api functions that will become available in future
21842203
// 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)