Skip to content

Commit 7cc0aba

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 c8dff28 commit 7cc0aba

File tree

5 files changed

+43
-0
lines changed

5 files changed

+43
-0
lines changed

compiler/rustc_codegen_llvm/src/base.rs

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -174,3 +174,12 @@ pub(crate) fn visibility_to_llvm(linkage: Visibility) -> llvm::Visibility {
174174
Visibility::Protected => llvm::Visibility::Protected,
175175
}
176176
}
177+
178+
pub(crate) fn set_variable_sanitizer_attrs(llval: &Value, attrs: &CodegenFnAttrs) {
179+
if attrs.no_sanitize.contains(SanitizerSet::ADDRESS) {
180+
unsafe { llvm::LLVMRustSetNoSanitizeAddress(llval) };
181+
}
182+
if attrs.no_sanitize.contains(SanitizerSet::HWADDRESS) {
183+
unsafe { llvm::LLVMRustSetNoSanitizeHWAddress(llval) };
184+
}
185+
}

compiler/rustc_codegen_llvm/src/consts.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -533,6 +533,8 @@ impl<'ll> CodegenCx<'ll, '_> {
533533
base::set_link_section(g, attrs);
534534
}
535535

536+
base::set_variable_sanitizer_attrs(g, attrs);
537+
536538
if attrs.flags.contains(CodegenFnAttrFlags::USED) {
537539
// `USED` and `USED_LINKER` can't be used together.
538540
assert!(!attrs.flags.contains(CodegenFnAttrFlags::USED_LINKER));

compiler/rustc_codegen_llvm/src/llvm/ffi.rs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2452,4 +2452,7 @@ unsafe extern "C" {
24522452
pub fn LLVMRustIs64BitSymbolicFile(buf_ptr: *const u8, buf_len: usize) -> bool;
24532453

24542454
pub fn LLVMRustIsECObject(buf_ptr: *const u8, buf_len: usize) -> bool;
2455+
2456+
pub fn LLVMRustSetNoSanitizeAddress(Global: &Value);
2457+
pub fn LLVMRustSetNoSanitizeHWAddress(Global: &Value);
24552458
}

compiler/rustc_llvm/llvm-wrapper/RustWrapper.cpp

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2189,6 +2189,25 @@ extern "C" bool LLVMRustLLVMHasZstdCompressionForDebugSymbols() {
21892189
return llvm::compression::zstd::isAvailable();
21902190
}
21912191

2192+
extern "C" void LLVMRustSetNoSanitizeAddress(LLVMValueRef Global) {
2193+
GlobalValue &GV = *unwrap<GlobalValue>(Global);
2194+
GlobalValue::SanitizerMetadata MD;
2195+
if (GV.hasSanitizerMetadata())
2196+
MD = GV.getSanitizerMetadata();
2197+
MD.NoAddress = true;
2198+
MD.IsDynInit = false;
2199+
GV.setSanitizerMetadata(MD);
2200+
}
2201+
2202+
extern "C" void LLVMRustSetNoSanitizeHWAddress(LLVMValueRef Global) {
2203+
GlobalValue &GV = *unwrap<GlobalValue>(Global);
2204+
GlobalValue::SanitizerMetadata MD;
2205+
if (GV.hasSanitizerMetadata())
2206+
MD = GV.getSanitizerMetadata();
2207+
MD.NoHWAddress = true;
2208+
GV.setSanitizerMetadata(MD);
2209+
}
2210+
21922211
// Operations on composite constants.
21932212
// These are clones of LLVM api functions that will become available in future
21942213
// releases. They can be removed once Rust's minimum supported LLVM version

tests/codegen/sanitizer/no-sanitize.rs

Lines changed: 10 additions & 0 deletions
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)