diff options
| author | 许杰友 Jieyou Xu (Joe) <39484203+jieyouxu@users.noreply.github.com> | 2024-11-23 20:19:51 +0800 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2024-11-23 20:19:51 +0800 |
| commit | c6d36256a6e6b7263eef2fa3f5aafef07768ac99 (patch) | |
| tree | 04ac9ad89a2d29b85e43271187de4c34b81d9e6a /compiler | |
| parent | 6e1c11591fc7e98015f8e793a15c8faf0bda67f1 (diff) | |
| parent | 204b2281fa508cf512d343cb1631955a5dfa9e0e (diff) | |
| download | rust-c6d36256a6e6b7263eef2fa3f5aafef07768ac99.tar.gz rust-c6d36256a6e6b7263eef2fa3f5aafef07768ac99.zip | |
Rollup merge of #127483 - BertalanD:no_sanitize-global-var, r=rcvalle
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. (cc https://github.com/rust-lang/rust/issues/39699)
Diffstat (limited to 'compiler')
| -rw-r--r-- | compiler/rustc_codegen_llvm/src/base.rs | 9 | ||||
| -rw-r--r-- | compiler/rustc_codegen_llvm/src/consts.rs | 2 | ||||
| -rw-r--r-- | compiler/rustc_codegen_llvm/src/llvm/ffi.rs | 3 | ||||
| -rw-r--r-- | compiler/rustc_llvm/llvm-wrapper/RustWrapper.cpp | 19 | ||||
| -rw-r--r-- | compiler/rustc_passes/messages.ftl | 4 | ||||
| -rw-r--r-- | compiler/rustc_passes/src/check_attr.rs | 37 | ||||
| -rw-r--r-- | compiler/rustc_passes/src/errors.rs | 11 |
7 files changed, 82 insertions, 3 deletions
diff --git a/compiler/rustc_codegen_llvm/src/base.rs b/compiler/rustc_codegen_llvm/src/base.rs index 32793894794..f62310bd948 100644 --- a/compiler/rustc_codegen_llvm/src/base.rs +++ b/compiler/rustc_codegen_llvm/src/base.rs @@ -172,3 +172,12 @@ pub(crate) fn visibility_to_llvm(linkage: Visibility) -> llvm::Visibility { Visibility::Protected => llvm::Visibility::Protected, } } + +pub(crate) 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) }; + } +} diff --git a/compiler/rustc_codegen_llvm/src/consts.rs b/compiler/rustc_codegen_llvm/src/consts.rs index 6f5ffbb4b34..c7114480d8b 100644 --- a/compiler/rustc_codegen_llvm/src/consts.rs +++ b/compiler/rustc_codegen_llvm/src/consts.rs @@ -470,6 +470,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)); diff --git a/compiler/rustc_codegen_llvm/src/llvm/ffi.rs b/compiler/rustc_codegen_llvm/src/llvm/ffi.rs index 7f59264824e..17b0ec4b936 100644 --- a/compiler/rustc_codegen_llvm/src/llvm/ffi.rs +++ b/compiler/rustc_codegen_llvm/src/llvm/ffi.rs @@ -2460,4 +2460,7 @@ unsafe extern "C" { pub fn LLVMRustIs64BitSymbolicFile(buf_ptr: *const u8, buf_len: usize) -> bool; pub fn LLVMRustIsECObject(buf_ptr: *const u8, buf_len: usize) -> bool; + + pub fn LLVMRustSetNoSanitizeAddress(Global: &Value); + pub fn LLVMRustSetNoSanitizeHWAddress(Global: &Value); } diff --git a/compiler/rustc_llvm/llvm-wrapper/RustWrapper.cpp b/compiler/rustc_llvm/llvm-wrapper/RustWrapper.cpp index cd70c3f2669..06550728f0f 100644 --- a/compiler/rustc_llvm/llvm-wrapper/RustWrapper.cpp +++ b/compiler/rustc_llvm/llvm-wrapper/RustWrapper.cpp @@ -2051,6 +2051,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 diff --git a/compiler/rustc_passes/messages.ftl b/compiler/rustc_passes/messages.ftl index 08098ae7f6c..0712af422ad 100644 --- a/compiler/rustc_passes/messages.ftl +++ b/compiler/rustc_passes/messages.ftl @@ -558,6 +558,10 @@ passes_no_mangle_foreign = passes_no_patterns = patterns not allowed in naked function parameters +passes_no_sanitize = + `#[no_sanitize({$attr_str})]` should be applied to {$accepted_kind} + .label = not {$accepted_kind} + passes_non_exported_macro_invalid_attrs = attribute should be applied to function or closure .label = not a function or closure diff --git a/compiler/rustc_passes/src/check_attr.rs b/compiler/rustc_passes/src/check_attr.rs index 87069e0b057..074fe77324f 100644 --- a/compiler/rustc_passes/src/check_attr.rs +++ b/compiler/rustc_passes/src/check_attr.rs @@ -126,9 +126,7 @@ impl<'tcx> CheckAttrVisitor<'tcx> { [sym::inline, ..] => self.check_inline(hir_id, attr, span, target), [sym::coverage, ..] => self.check_coverage(attr, span, target), [sym::optimize, ..] => self.check_optimize(hir_id, attr, span, target), - [sym::no_sanitize, ..] => { - self.check_applied_to_fn_or_method(hir_id, attr, span, target) - } + [sym::no_sanitize, ..] => self.check_no_sanitize(attr, span, target), [sym::non_exhaustive, ..] => self.check_non_exhaustive(hir_id, attr, span, target), [sym::marker, ..] => self.check_marker(hir_id, attr, span, target), [sym::target_feature, ..] => { @@ -450,6 +448,39 @@ impl<'tcx> CheckAttrVisitor<'tcx> { } } + fn check_no_sanitize(&self, attr: &Attribute, span: Span, target: Target) { + if let Some(list) = attr.meta_item_list() { + for item in list.iter() { + let sym = item.name_or_empty(); + match sym { + sym::address | sym::hwaddress => { + let is_valid = + matches!(target, Target::Fn | Target::Method(..) | Target::Static); + if !is_valid { + self.dcx().emit_err(errors::NoSanitize { + attr_span: item.span(), + defn_span: span, + accepted_kind: "a function or static", + attr_str: sym.as_str(), + }); + } + } + _ => { + let is_valid = matches!(target, Target::Fn | Target::Method(..)); + if !is_valid { + self.dcx().emit_err(errors::NoSanitize { + attr_span: item.span(), + defn_span: span, + accepted_kind: "a function", + attr_str: sym.as_str(), + }); + } + } + } + } + } + } + fn check_generic_attr( &self, hir_id: HirId, diff --git a/compiler/rustc_passes/src/errors.rs b/compiler/rustc_passes/src/errors.rs index 2d1734c0314..fbf25cb476a 100644 --- a/compiler/rustc_passes/src/errors.rs +++ b/compiler/rustc_passes/src/errors.rs @@ -1846,3 +1846,14 @@ pub(crate) struct AttrCrateLevelOnlySugg { #[primary_span] pub attr: Span, } + +#[derive(Diagnostic)] +#[diag(passes_no_sanitize)] +pub(crate) struct NoSanitize<'a> { + #[primary_span] + pub attr_span: Span, + #[label] + pub defn_span: Span, + pub accepted_kind: &'a str, + pub attr_str: &'a str, +} |
