diff options
| author | Bastian Kersting <bkersting@google.com> | 2025-06-18 13:47:44 +0000 |
|---|---|---|
| committer | Bastian Kersting <bkersting@google.com> | 2025-08-18 08:45:28 +0000 |
| commit | 95bdb34494ad795f552cab7a0eb7bfd2e98ef033 (patch) | |
| tree | 452b242828e0dce60cd3f0b14f651e7509e13ff2 /compiler/rustc_codegen_ssa/src | |
| parent | 3ef065bf872ce62a18336dca0daf47b3e9f7da64 (diff) | |
| download | rust-95bdb34494ad795f552cab7a0eb7bfd2e98ef033.tar.gz rust-95bdb34494ad795f552cab7a0eb7bfd2e98ef033.zip | |
Remove the no_sanitize attribute in favor of sanitize
This removes the #[no_sanitize] attribute, which was behind an unstable feature named no_sanitize. Instead, we introduce the sanitize attribute which is more powerful and allows to be extended in the future (instead of just focusing on turning sanitizers off). This also makes sanitize(kernel_address = ..) attribute work with -Zsanitize=address To do it the same as how clang disables address sanitizer, we now disable ASAN on sanitize(kernel_address = "off") and KASAN on sanitize(address = "off"). The same was added to clang in https://reviews.llvm.org/D44981.
Diffstat (limited to 'compiler/rustc_codegen_ssa/src')
| -rw-r--r-- | compiler/rustc_codegen_ssa/src/codegen_attrs.rs | 78 | ||||
| -rw-r--r-- | compiler/rustc_codegen_ssa/src/errors.rs | 8 |
2 files changed, 22 insertions, 64 deletions
diff --git a/compiler/rustc_codegen_ssa/src/codegen_attrs.rs b/compiler/rustc_codegen_ssa/src/codegen_attrs.rs index 068559497dd..bf14c02a09c 100644 --- a/compiler/rustc_codegen_ssa/src/codegen_attrs.rs +++ b/compiler/rustc_codegen_ssa/src/codegen_attrs.rs @@ -77,32 +77,6 @@ fn parse_instruction_set_attr(tcx: TyCtxt<'_>, attr: &Attribute) -> Option<Instr } } -// FIXME(jdonszelmann): remove when no_sanitize becomes a parsed attr -fn parse_no_sanitize_attr(tcx: TyCtxt<'_>, attr: &Attribute) -> Option<SanitizerSet> { - let list = attr.meta_item_list()?; - let mut sanitizer_set = SanitizerSet::empty(); - - for item in list.iter() { - match item.name() { - Some(sym::address) => { - sanitizer_set |= SanitizerSet::ADDRESS | SanitizerSet::KERNELADDRESS - } - Some(sym::cfi) => sanitizer_set |= SanitizerSet::CFI, - Some(sym::kcfi) => sanitizer_set |= SanitizerSet::KCFI, - Some(sym::memory) => sanitizer_set |= SanitizerSet::MEMORY, - Some(sym::memtag) => sanitizer_set |= SanitizerSet::MEMTAG, - Some(sym::shadow_call_stack) => sanitizer_set |= SanitizerSet::SHADOWCALLSTACK, - Some(sym::thread) => sanitizer_set |= SanitizerSet::THREAD, - Some(sym::hwaddress) => sanitizer_set |= SanitizerSet::HWADDRESS, - _ => { - tcx.dcx().emit_err(errors::InvalidNoSanitize { span: item.span() }); - } - } - } - - Some(sanitizer_set) -} - // FIXME(jdonszelmann): remove when patchable_function_entry becomes a parsed attr fn parse_patchable_function_entry( tcx: TyCtxt<'_>, @@ -161,7 +135,6 @@ fn parse_patchable_function_entry( #[derive(Default)] struct InterestingAttributeDiagnosticSpans { link_ordinal: Option<Span>, - no_sanitize: Option<Span>, sanitize: Option<Span>, inline: Option<Span>, no_mangle: Option<Span>, @@ -331,11 +304,6 @@ fn process_builtin_attrs( codegen_fn_attrs.flags |= CodegenFnAttrFlags::ALLOCATOR_ZEROED } sym::thread_local => codegen_fn_attrs.flags |= CodegenFnAttrFlags::THREAD_LOCAL, - sym::no_sanitize => { - interesting_spans.no_sanitize = Some(attr.span()); - codegen_fn_attrs.no_sanitize |= - parse_no_sanitize_attr(tcx, attr).unwrap_or_default(); - } sym::sanitize => interesting_spans.sanitize = Some(attr.span()), sym::instruction_set => { codegen_fn_attrs.instruction_set = parse_instruction_set_attr(tcx, attr) @@ -459,21 +427,10 @@ fn check_result( if !codegen_fn_attrs.no_sanitize.is_empty() && codegen_fn_attrs.inline.always() && let (Some(no_sanitize_span), Some(inline_span)) = - (interesting_spans.no_sanitize, interesting_spans.inline) - { - let hir_id = tcx.local_def_id_to_hir_id(did); - tcx.node_span_lint(lint::builtin::INLINE_NO_SANITIZE, hir_id, no_sanitize_span, |lint| { - lint.primary_message("`no_sanitize` will have no effect after inlining"); - lint.span_note(inline_span, "inlining requested here"); - }) - } - if !codegen_fn_attrs.no_sanitize.is_empty() - && codegen_fn_attrs.inline.always() - && let (Some(sanitize_span), Some(inline_span)) = (interesting_spans.sanitize, interesting_spans.inline) { let hir_id = tcx.local_def_id_to_hir_id(did); - tcx.node_span_lint(lint::builtin::INLINE_NO_SANITIZE, hir_id, sanitize_span, |lint| { + tcx.node_span_lint(lint::builtin::INLINE_NO_SANITIZE, hir_id, no_sanitize_span, |lint| { lint.primary_message("setting `sanitize` off will have no effect after inlining"); lint.span_note(inline_span, "inlining requested here"); }) @@ -601,9 +558,14 @@ fn opt_trait_item(tcx: TyCtxt<'_>, def_id: DefId) -> Option<DefId> { } /// For an attr that has the `sanitize` attribute, read the list of -/// disabled sanitizers. -fn parse_sanitize_attr(tcx: TyCtxt<'_>, attr: &Attribute) -> SanitizerSet { - let mut result = SanitizerSet::empty(); +/// disabled sanitizers. `current_attr` holds the information about +/// previously parsed attributes. +fn parse_sanitize_attr( + tcx: TyCtxt<'_>, + attr: &Attribute, + current_attr: SanitizerSet, +) -> SanitizerSet { + let mut result = current_attr; if let Some(list) = attr.meta_item_list() { for item in list.iter() { let MetaItemInner::MetaItem(set) = item else { @@ -612,10 +574,13 @@ fn parse_sanitize_attr(tcx: TyCtxt<'_>, attr: &Attribute) -> SanitizerSet { }; let segments = set.path.segments.iter().map(|x| x.ident.name).collect::<Vec<_>>(); match segments.as_slice() { - [sym::address] if set.value_str() == Some(sym::off) => { + // Similar to clang, sanitize(address = ..) and + // sanitize(kernel_address = ..) control both ASan and KASan + // Source: https://reviews.llvm.org/D44981. + [sym::address] | [sym::kernel_address] if set.value_str() == Some(sym::off) => { result |= SanitizerSet::ADDRESS | SanitizerSet::KERNELADDRESS } - [sym::address] if set.value_str() == Some(sym::on) => { + [sym::address] | [sym::kernel_address] if set.value_str() == Some(sym::on) => { result &= !SanitizerSet::ADDRESS; result &= !SanitizerSet::KERNELADDRESS; } @@ -663,19 +628,20 @@ fn parse_sanitize_attr(tcx: TyCtxt<'_>, attr: &Attribute) -> SanitizerSet { } fn disabled_sanitizers_for(tcx: TyCtxt<'_>, did: LocalDefId) -> SanitizerSet { - // Check for a sanitize annotation directly on this def. - if let Some(attr) = tcx.get_attr(did, sym::sanitize) { - return parse_sanitize_attr(tcx, attr); - } - - // Otherwise backtrack. - match tcx.opt_local_parent(did) { + // Backtrack to the crate root. + let disabled = match tcx.opt_local_parent(did) { // Check the parent (recursively). Some(parent) => tcx.disabled_sanitizers_for(parent), // We reached the crate root without seeing an attribute, so // there is no sanitizers to exclude. None => SanitizerSet::empty(), + }; + + // Check for a sanitize annotation directly on this def. + if let Some(attr) = tcx.get_attr(did, sym::sanitize) { + return parse_sanitize_attr(tcx, attr, disabled); } + disabled } /// Checks if the provided DefId is a method in a trait impl for a trait which has track_caller diff --git a/compiler/rustc_codegen_ssa/src/errors.rs b/compiler/rustc_codegen_ssa/src/errors.rs index 913e0025f2e..209c78ddeda 100644 --- a/compiler/rustc_codegen_ssa/src/errors.rs +++ b/compiler/rustc_codegen_ssa/src/errors.rs @@ -1121,14 +1121,6 @@ impl IntoDiagArg for ExpectedPointerMutability { } #[derive(Diagnostic)] -#[diag(codegen_ssa_invalid_no_sanitize)] -#[note] -pub(crate) struct InvalidNoSanitize { - #[primary_span] - pub span: Span, -} - -#[derive(Diagnostic)] #[diag(codegen_ssa_invalid_sanitize)] #[note] pub(crate) struct InvalidSanitize { |
