add realtime sanitizer
This commit is contained in:
parent
bc883e24b8
commit
d198633b95
34 changed files with 240 additions and 38 deletions
|
|
@ -1,4 +1,4 @@
|
|||
use rustc_hir::attrs::{CoverageAttrKind, OptimizeAttr, SanitizerSet, UsedBy};
|
||||
use rustc_hir::attrs::{CoverageAttrKind, OptimizeAttr, RtsanSetting, SanitizerSet, UsedBy};
|
||||
use rustc_session::parse::feature_err;
|
||||
|
||||
use super::prelude::*;
|
||||
|
|
@ -592,7 +592,8 @@ impl<S: Stage> SingleAttributeParser<S> for SanitizeParser {
|
|||
r#"memory = "on|off""#,
|
||||
r#"memtag = "on|off""#,
|
||||
r#"shadow_call_stack = "on|off""#,
|
||||
r#"thread = "on|off""#
|
||||
r#"thread = "on|off""#,
|
||||
r#"realtime = "nonblocking|blocking|caller""#,
|
||||
]);
|
||||
|
||||
const ATTRIBUTE_ORDER: AttributeOrder = AttributeOrder::KeepOutermost;
|
||||
|
|
@ -606,6 +607,7 @@ impl<S: Stage> SingleAttributeParser<S> for SanitizeParser {
|
|||
|
||||
let mut on_set = SanitizerSet::empty();
|
||||
let mut off_set = SanitizerSet::empty();
|
||||
let mut rtsan = None;
|
||||
|
||||
for item in list.mixed() {
|
||||
let Some(item) = item.meta_item() else {
|
||||
|
|
@ -654,6 +656,17 @@ impl<S: Stage> SingleAttributeParser<S> for SanitizeParser {
|
|||
Some(sym::shadow_call_stack) => apply(SanitizerSet::SHADOWCALLSTACK),
|
||||
Some(sym::thread) => apply(SanitizerSet::THREAD),
|
||||
Some(sym::hwaddress) => apply(SanitizerSet::HWADDRESS),
|
||||
Some(sym::realtime) => match value.value_as_str() {
|
||||
Some(sym::nonblocking) => rtsan = Some(RtsanSetting::Nonblocking),
|
||||
Some(sym::blocking) => rtsan = Some(RtsanSetting::Blocking),
|
||||
Some(sym::caller) => rtsan = Some(RtsanSetting::Caller),
|
||||
_ => {
|
||||
cx.expected_specific_argument_strings(
|
||||
value.value_span,
|
||||
&[sym::nonblocking, sym::blocking, sym::caller],
|
||||
);
|
||||
}
|
||||
},
|
||||
_ => {
|
||||
cx.expected_specific_argument_strings(
|
||||
item.path().span(),
|
||||
|
|
@ -666,6 +679,7 @@ impl<S: Stage> SingleAttributeParser<S> for SanitizeParser {
|
|||
sym::shadow_call_stack,
|
||||
sym::thread,
|
||||
sym::hwaddress,
|
||||
sym::realtime,
|
||||
],
|
||||
);
|
||||
continue;
|
||||
|
|
@ -673,7 +687,7 @@ impl<S: Stage> SingleAttributeParser<S> for SanitizeParser {
|
|||
}
|
||||
}
|
||||
|
||||
Some(AttributeKind::Sanitize { on_set, off_set, span: cx.attr_span })
|
||||
Some(AttributeKind::Sanitize { on_set, off_set, rtsan, span: cx.attr_span })
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
//! Set and unset common attributes on LLVM values.
|
||||
use rustc_hir::attrs::{InlineAttr, InstructionSetAttr, OptimizeAttr};
|
||||
use rustc_hir::attrs::{InlineAttr, InstructionSetAttr, OptimizeAttr, RtsanSetting};
|
||||
use rustc_hir::def_id::DefId;
|
||||
use rustc_middle::middle::codegen_fn_attrs::{
|
||||
CodegenFnAttrFlags, CodegenFnAttrs, PatchableFunctionEntry, SanitizerFnAttrs,
|
||||
|
|
@ -131,6 +131,18 @@ pub(crate) fn sanitize_attrs<'ll, 'tcx>(
|
|||
if enabled.contains(SanitizerSet::SAFESTACK) {
|
||||
attrs.push(llvm::AttributeKind::SanitizeSafeStack.create_attr(cx.llcx));
|
||||
}
|
||||
if tcx.sess.sanitizers().contains(SanitizerSet::REALTIME) {
|
||||
match sanitizer_fn_attr.rtsan_setting {
|
||||
RtsanSetting::Nonblocking => {
|
||||
attrs.push(llvm::AttributeKind::SanitizeRealtimeNonblocking.create_attr(cx.llcx))
|
||||
}
|
||||
RtsanSetting::Blocking => {
|
||||
attrs.push(llvm::AttributeKind::SanitizeRealtimeBlocking.create_attr(cx.llcx))
|
||||
}
|
||||
// caller is the default, so no llvm attribute
|
||||
RtsanSetting::Caller => (),
|
||||
}
|
||||
}
|
||||
attrs
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -633,6 +633,7 @@ pub(crate) unsafe fn llvm_optimize(
|
|||
sanitize_memory: config.sanitizer.contains(SanitizerSet::MEMORY),
|
||||
sanitize_memory_recover: config.sanitizer_recover.contains(SanitizerSet::MEMORY),
|
||||
sanitize_memory_track_origins: config.sanitizer_memory_track_origins as c_int,
|
||||
sanitize_realtime: config.sanitizer.contains(SanitizerSet::REALTIME),
|
||||
sanitize_thread: config.sanitizer.contains(SanitizerSet::THREAD),
|
||||
sanitize_hwaddress: config.sanitizer.contains(SanitizerSet::HWADDRESS),
|
||||
sanitize_hwaddress_recover: config.sanitizer_recover.contains(SanitizerSet::HWADDRESS),
|
||||
|
|
|
|||
|
|
@ -290,6 +290,8 @@ pub(crate) enum AttributeKind {
|
|||
DeadOnReturn = 44,
|
||||
CapturesReadOnly = 45,
|
||||
CapturesNone = 46,
|
||||
SanitizeRealtimeNonblocking = 47,
|
||||
SanitizeRealtimeBlocking = 48,
|
||||
}
|
||||
|
||||
/// LLVMIntPredicate
|
||||
|
|
@ -482,6 +484,7 @@ pub(crate) struct SanitizerOptions {
|
|||
pub sanitize_memory: bool,
|
||||
pub sanitize_memory_recover: bool,
|
||||
pub sanitize_memory_track_origins: c_int,
|
||||
pub sanitize_realtime: bool,
|
||||
pub sanitize_thread: bool,
|
||||
pub sanitize_hwaddress: bool,
|
||||
pub sanitize_hwaddress_recover: bool,
|
||||
|
|
|
|||
|
|
@ -1252,6 +1252,9 @@ fn add_sanitizer_libraries(
|
|||
if sanitizer.contains(SanitizerSet::SAFESTACK) {
|
||||
link_sanitizer_runtime(sess, flavor, linker, "safestack");
|
||||
}
|
||||
if sanitizer.contains(SanitizerSet::REALTIME) {
|
||||
link_sanitizer_runtime(sess, flavor, linker, "rtsan");
|
||||
}
|
||||
}
|
||||
|
||||
fn link_sanitizer_runtime(
|
||||
|
|
|
|||
|
|
@ -349,9 +349,10 @@ fn apply_overrides(tcx: TyCtxt<'_>, did: LocalDefId, codegen_fn_attrs: &mut Code
|
|||
codegen_fn_attrs.alignment =
|
||||
Ord::max(codegen_fn_attrs.alignment, tcx.sess.opts.unstable_opts.min_function_alignment);
|
||||
|
||||
// Compute the disabled sanitizers.
|
||||
codegen_fn_attrs.sanitizers.disabled |=
|
||||
tcx.sanitizer_settings_for(did).disabled;
|
||||
// Passed in sanitizer settings are always the default.
|
||||
assert!(codegen_fn_attrs.sanitizers == SanitizerFnAttrs::default());
|
||||
// Replace with #[sanitize] value
|
||||
codegen_fn_attrs.sanitizers = tcx.sanitizer_settings_for(did);
|
||||
// On trait methods, inherit the `#[align]` of the trait's method prototype.
|
||||
codegen_fn_attrs.alignment = Ord::max(codegen_fn_attrs.alignment, tcx.inherited_align(did));
|
||||
|
||||
|
|
@ -587,7 +588,7 @@ fn sanitizer_settings_for(tcx: TyCtxt<'_>, did: LocalDefId) -> SanitizerFnAttrs
|
|||
};
|
||||
|
||||
// Check for a sanitize annotation directly on this def.
|
||||
if let Some((on_set, off_set)) = find_attr!(tcx.get_all_attrs(did), AttributeKind::Sanitize {on_set, off_set, ..} => (on_set, off_set))
|
||||
if let Some((on_set, off_set, rtsan)) = find_attr!(tcx.get_all_attrs(did), AttributeKind::Sanitize {on_set, off_set, rtsan, ..} => (on_set, off_set, rtsan))
|
||||
{
|
||||
// the on set is the set of sanitizers explicitly enabled.
|
||||
// we mask those out since we want the set of disabled sanitizers here
|
||||
|
|
@ -598,6 +599,11 @@ fn sanitizer_settings_for(tcx: TyCtxt<'_>, did: LocalDefId) -> SanitizerFnAttrs
|
|||
// the on set and off set are distjoint since there's a third option: unset.
|
||||
// a node may not set the sanitizer setting in which case it inherits from parents.
|
||||
// the code above in this function does this backtracking
|
||||
|
||||
// if rtsan was specified here override the parent
|
||||
if let Some(rtsan) = rtsan {
|
||||
settings.rtsan_setting = *rtsan;
|
||||
}
|
||||
}
|
||||
settings
|
||||
}
|
||||
|
|
|
|||
|
|
@ -382,6 +382,16 @@ pub struct DebugVisualizer {
|
|||
pub path: Symbol,
|
||||
}
|
||||
|
||||
#[derive(Clone, Copy, Debug, Decodable, Encodable, Eq, PartialEq)]
|
||||
#[derive(HashStable_Generic, PrintAttribute)]
|
||||
#[derive_const(Default)]
|
||||
pub enum RtsanSetting {
|
||||
Nonblocking,
|
||||
Blocking,
|
||||
#[default]
|
||||
Caller,
|
||||
}
|
||||
|
||||
/// Represents parsed *built-in* inert attributes.
|
||||
///
|
||||
/// ## Overview
|
||||
|
|
@ -689,7 +699,13 @@ pub enum AttributeKind {
|
|||
///
|
||||
/// the on set and off set are distjoint since there's a third option: unset.
|
||||
/// a node may not set the sanitizer setting in which case it inherits from parents.
|
||||
Sanitize { on_set: SanitizerSet, off_set: SanitizerSet, span: Span },
|
||||
/// rtsan is unset if None
|
||||
Sanitize {
|
||||
on_set: SanitizerSet,
|
||||
off_set: SanitizerSet,
|
||||
rtsan: Option<RtsanSetting>,
|
||||
span: Span,
|
||||
},
|
||||
|
||||
/// Represents `#[should_panic]`
|
||||
ShouldPanic { reason: Option<Symbol>, span: Span },
|
||||
|
|
|
|||
|
|
@ -6,6 +6,9 @@
|
|||
#![cfg_attr(bootstrap, feature(debug_closure_helpers))]
|
||||
#![feature(associated_type_defaults)]
|
||||
#![feature(closure_track_caller)]
|
||||
#![feature(const_default)]
|
||||
#![feature(const_trait_impl)]
|
||||
#![feature(derive_const)]
|
||||
#![feature(exhaustive_patterns)]
|
||||
#![feature(never_type)]
|
||||
#![feature(variant_count)]
|
||||
|
|
|
|||
|
|
@ -38,6 +38,7 @@
|
|||
#include "llvm/Transforms/Instrumentation/HWAddressSanitizer.h"
|
||||
#include "llvm/Transforms/Instrumentation/InstrProfiling.h"
|
||||
#include "llvm/Transforms/Instrumentation/MemorySanitizer.h"
|
||||
#include "llvm/Transforms/Instrumentation/RealtimeSanitizer.h"
|
||||
#include "llvm/Transforms/Instrumentation/ThreadSanitizer.h"
|
||||
#include "llvm/Transforms/Scalar/AnnotationRemarks.h"
|
||||
#include "llvm/Transforms/Utils/CanonicalizeAliases.h"
|
||||
|
|
@ -531,6 +532,7 @@ struct LLVMRustSanitizerOptions {
|
|||
bool SanitizeMemory;
|
||||
bool SanitizeMemoryRecover;
|
||||
int SanitizeMemoryTrackOrigins;
|
||||
bool SanitizerRealtime;
|
||||
bool SanitizeThread;
|
||||
bool SanitizeHWAddress;
|
||||
bool SanitizeHWAddressRecover;
|
||||
|
|
@ -786,6 +788,13 @@ extern "C" LLVMRustResult LLVMRustOptimize(
|
|||
MPM.addPass(HWAddressSanitizerPass(opts));
|
||||
});
|
||||
}
|
||||
if (SanitizerOptions->SanitizerRealtime) {
|
||||
OptimizerLastEPCallbacks.push_back([](ModulePassManager &MPM,
|
||||
OptimizationLevel Level,
|
||||
ThinOrFullLTOPhase phase) {
|
||||
MPM.addPass(RealtimeSanitizerPass());
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
ModulePassManager MPM;
|
||||
|
|
|
|||
|
|
@ -246,6 +246,8 @@ enum class LLVMRustAttributeKind {
|
|||
DeadOnReturn = 44,
|
||||
CapturesReadOnly = 45,
|
||||
CapturesNone = 46,
|
||||
SanitizeRealtimeNonblocking = 47,
|
||||
SanitizeRealtimeBlocking = 48,
|
||||
};
|
||||
|
||||
static Attribute::AttrKind fromRust(LLVMRustAttributeKind Kind) {
|
||||
|
|
@ -342,6 +344,10 @@ static Attribute::AttrKind fromRust(LLVMRustAttributeKind Kind) {
|
|||
case LLVMRustAttributeKind::CapturesReadOnly:
|
||||
case LLVMRustAttributeKind::CapturesNone:
|
||||
report_fatal_error("Should be handled separately");
|
||||
case LLVMRustAttributeKind::SanitizeRealtimeNonblocking:
|
||||
return Attribute::SanitizeRealtime;
|
||||
case LLVMRustAttributeKind::SanitizeRealtimeBlocking:
|
||||
return Attribute::SanitizeRealtimeBlocking;
|
||||
}
|
||||
report_fatal_error("bad LLVMRustAttributeKind");
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
use std::borrow::Cow;
|
||||
|
||||
use rustc_abi::Align;
|
||||
use rustc_hir::attrs::{InlineAttr, InstructionSetAttr, Linkage, OptimizeAttr};
|
||||
use rustc_hir::attrs::{InlineAttr, InstructionSetAttr, Linkage, OptimizeAttr, RtsanSetting};
|
||||
use rustc_macros::{HashStable, TyDecodable, TyEncodable};
|
||||
use rustc_span::Symbol;
|
||||
use rustc_target::spec::SanitizerSet;
|
||||
|
|
@ -245,11 +245,11 @@ impl CodegenFnAttrs {
|
|||
#[derive(Clone, Copy, Debug, HashStable, TyEncodable, TyDecodable, Eq, PartialEq)]
|
||||
pub struct SanitizerFnAttrs {
|
||||
pub disabled: SanitizerSet,
|
||||
pub rtsan_setting: RtsanSetting,
|
||||
}
|
||||
|
||||
impl const Default for SanitizerFnAttrs {
|
||||
fn default() -> Self {
|
||||
Self { disabled: SanitizerSet::empty() }
|
||||
Self { disabled: SanitizerSet::empty(), rtsan_setting: RtsanSetting::default() }
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -212,7 +212,7 @@ impl<'tcx> CheckAttrVisitor<'tcx> {
|
|||
&Attribute::Parsed(AttributeKind::CustomMir(dialect, phase, attr_span)) => {
|
||||
self.check_custom_mir(dialect, phase, attr_span)
|
||||
}
|
||||
&Attribute::Parsed(AttributeKind::Sanitize { on_set, off_set, span: attr_span}) => {
|
||||
&Attribute::Parsed(AttributeKind::Sanitize { on_set, off_set, rtsan: _, span: attr_span}) => {
|
||||
self.check_sanitize(attr_span, on_set | off_set, span, target);
|
||||
},
|
||||
Attribute::Parsed(AttributeKind::Link(_, attr_span)) => {
|
||||
|
|
|
|||
|
|
@ -808,7 +808,7 @@ mod desc {
|
|||
pub(crate) const parse_opt_panic_strategy: &str = parse_panic_strategy;
|
||||
pub(crate) const parse_oom_strategy: &str = "either `panic` or `abort`";
|
||||
pub(crate) const parse_relro_level: &str = "one of: `full`, `partial`, or `off`";
|
||||
pub(crate) const parse_sanitizers: &str = "comma separated list of sanitizers: `address`, `cfi`, `dataflow`, `hwaddress`, `kcfi`, `kernel-address`, `leak`, `memory`, `memtag`, `safestack`, `shadow-call-stack`, or `thread`";
|
||||
pub(crate) const parse_sanitizers: &str = "comma separated list of sanitizers: `address`, `cfi`, `dataflow`, `hwaddress`, `kcfi`, `kernel-address`, `leak`, `memory`, `memtag`, `safestack`, `shadow-call-stack`, `thread`, or 'realtime'";
|
||||
pub(crate) const parse_sanitizer_memory_track_origins: &str = "0, 1, or 2";
|
||||
pub(crate) const parse_cfguard: &str =
|
||||
"either a boolean (`yes`, `no`, `on`, `off`, etc), `checks`, or `nochecks`";
|
||||
|
|
@ -1253,6 +1253,7 @@ pub mod parse {
|
|||
"thread" => SanitizerSet::THREAD,
|
||||
"hwaddress" => SanitizerSet::HWADDRESS,
|
||||
"safestack" => SanitizerSet::SAFESTACK,
|
||||
"realtime" => SanitizerSet::REALTIME,
|
||||
_ => return false,
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -583,6 +583,7 @@ symbols! {
|
|||
bitxor_assign,
|
||||
black_box,
|
||||
block,
|
||||
blocking,
|
||||
bool,
|
||||
bool_then,
|
||||
borrowck_graphviz_format,
|
||||
|
|
@ -616,6 +617,7 @@ symbols! {
|
|||
call_once,
|
||||
call_once_future,
|
||||
call_ref_future,
|
||||
caller,
|
||||
caller_location,
|
||||
capture_disjoint_fields,
|
||||
carrying_mul_add,
|
||||
|
|
@ -1561,6 +1563,7 @@ symbols! {
|
|||
non_exhaustive_omitted_patterns_lint,
|
||||
non_lifetime_binders,
|
||||
non_modrs_mods,
|
||||
nonblocking,
|
||||
none,
|
||||
nontemporal_store,
|
||||
noop_method_borrow,
|
||||
|
|
@ -1801,6 +1804,7 @@ symbols! {
|
|||
read_via_copy,
|
||||
readonly,
|
||||
realloc,
|
||||
realtime,
|
||||
reason,
|
||||
reborrow,
|
||||
receiver,
|
||||
|
|
|
|||
|
|
@ -1177,6 +1177,7 @@ bitflags::bitflags! {
|
|||
const KERNELADDRESS = 1 << 9;
|
||||
const SAFESTACK = 1 << 10;
|
||||
const DATAFLOW = 1 << 11;
|
||||
const REALTIME = 1 << 12;
|
||||
}
|
||||
}
|
||||
rustc_data_structures::external_bitflags_debug! { SanitizerSet }
|
||||
|
|
@ -1227,6 +1228,7 @@ impl SanitizerSet {
|
|||
SanitizerSet::SHADOWCALLSTACK => "shadow-call-stack",
|
||||
SanitizerSet::THREAD => "thread",
|
||||
SanitizerSet::HWADDRESS => "hwaddress",
|
||||
SanitizerSet::REALTIME => "realtime",
|
||||
_ => return None,
|
||||
})
|
||||
}
|
||||
|
|
@ -1271,6 +1273,7 @@ impl FromStr for SanitizerSet {
|
|||
"shadow-call-stack" => SanitizerSet::SHADOWCALLSTACK,
|
||||
"thread" => SanitizerSet::THREAD,
|
||||
"hwaddress" => SanitizerSet::HWADDRESS,
|
||||
"realtime" => SanitizerSet::REALTIME,
|
||||
s => return Err(format!("unknown sanitizer {s}")),
|
||||
})
|
||||
}
|
||||
|
|
|
|||
|
|
@ -20,7 +20,10 @@ pub(crate) fn target() -> Target {
|
|||
cpu: "apple-m1".into(),
|
||||
max_atomic_width: Some(128),
|
||||
// FIXME: The leak sanitizer currently fails the tests, see #88132.
|
||||
supported_sanitizers: SanitizerSet::ADDRESS | SanitizerSet::CFI | SanitizerSet::THREAD,
|
||||
supported_sanitizers: SanitizerSet::ADDRESS
|
||||
| SanitizerSet::CFI
|
||||
| SanitizerSet::THREAD
|
||||
| SanitizerSet::REALTIME,
|
||||
supports_xray: true,
|
||||
..opts
|
||||
},
|
||||
|
|
|
|||
|
|
@ -18,7 +18,9 @@ pub(crate) fn target() -> Target {
|
|||
options: TargetOptions {
|
||||
features: "+neon,+fp-armv8,+apple-a7".into(),
|
||||
max_atomic_width: Some(128),
|
||||
supported_sanitizers: SanitizerSet::ADDRESS | SanitizerSet::THREAD,
|
||||
supported_sanitizers: SanitizerSet::ADDRESS
|
||||
| SanitizerSet::THREAD
|
||||
| SanitizerSet::REALTIME,
|
||||
..opts
|
||||
},
|
||||
}
|
||||
|
|
|
|||
|
|
@ -18,7 +18,9 @@ pub(crate) fn target() -> Target {
|
|||
options: TargetOptions {
|
||||
features: "+neon,+fp-armv8,+apple-a7".into(),
|
||||
max_atomic_width: Some(128),
|
||||
supported_sanitizers: SanitizerSet::ADDRESS | SanitizerSet::THREAD,
|
||||
supported_sanitizers: SanitizerSet::ADDRESS
|
||||
| SanitizerSet::THREAD
|
||||
| SanitizerSet::REALTIME,
|
||||
..opts
|
||||
},
|
||||
}
|
||||
|
|
|
|||
|
|
@ -30,7 +30,8 @@ pub(crate) fn target() -> Target {
|
|||
| SanitizerSet::MEMORY
|
||||
| SanitizerSet::MEMTAG
|
||||
| SanitizerSet::THREAD
|
||||
| SanitizerSet::HWADDRESS,
|
||||
| SanitizerSet::HWADDRESS
|
||||
| SanitizerSet::REALTIME,
|
||||
supports_xray: true,
|
||||
..base::linux_gnu::opts()
|
||||
},
|
||||
|
|
|
|||
|
|
@ -21,7 +21,8 @@ pub(crate) fn target() -> Target {
|
|||
supported_sanitizers: SanitizerSet::ADDRESS
|
||||
| SanitizerSet::CFI
|
||||
| SanitizerSet::LEAK
|
||||
| SanitizerSet::THREAD,
|
||||
| SanitizerSet::THREAD
|
||||
| SanitizerSet::REALTIME,
|
||||
supports_xray: true,
|
||||
..opts
|
||||
},
|
||||
|
|
|
|||
|
|
@ -17,7 +17,8 @@ pub(crate) fn target() -> Target {
|
|||
| SanitizerSet::LEAK
|
||||
| SanitizerSet::MEMORY
|
||||
| SanitizerSet::SAFESTACK
|
||||
| SanitizerSet::THREAD;
|
||||
| SanitizerSet::THREAD
|
||||
| SanitizerSet::REALTIME;
|
||||
base.supports_xray = true;
|
||||
|
||||
Target {
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
Change this file to make users of the `download-ci-llvm` configuration download
|
||||
a new version of LLVM from CI, even if the LLVM submodule hasn’t changed.
|
||||
|
||||
Last change is for: https://github.com/rust-lang/rust/pull/139931
|
||||
Last change is for: https://github.com/rust-lang/rust/pull/147935
|
||||
|
|
|
|||
|
|
@ -1262,13 +1262,13 @@ fn supported_sanitizers(
|
|||
};
|
||||
|
||||
match &*target.triple {
|
||||
"aarch64-apple-darwin" => darwin_libs("osx", &["asan", "lsan", "tsan"]),
|
||||
"aarch64-apple-ios" => darwin_libs("ios", &["asan", "tsan"]),
|
||||
"aarch64-apple-ios-sim" => darwin_libs("iossim", &["asan", "tsan"]),
|
||||
"aarch64-apple-darwin" => darwin_libs("osx", &["asan", "lsan", "tsan", "rtsan"]),
|
||||
"aarch64-apple-ios" => darwin_libs("ios", &["asan", "tsan", "rtsan"]),
|
||||
"aarch64-apple-ios-sim" => darwin_libs("iossim", &["asan", "tsan", "rtsan"]),
|
||||
"aarch64-apple-ios-macabi" => darwin_libs("osx", &["asan", "lsan", "tsan"]),
|
||||
"aarch64-unknown-fuchsia" => common_libs("fuchsia", "aarch64", &["asan"]),
|
||||
"aarch64-unknown-linux-gnu" => {
|
||||
common_libs("linux", "aarch64", &["asan", "lsan", "msan", "tsan", "hwasan"])
|
||||
common_libs("linux", "aarch64", &["asan", "lsan", "msan", "tsan", "hwasan", "rtsan"])
|
||||
}
|
||||
"aarch64-unknown-linux-ohos" => {
|
||||
common_libs("linux", "aarch64", &["asan", "lsan", "msan", "tsan", "hwasan"])
|
||||
|
|
@ -1276,7 +1276,7 @@ fn supported_sanitizers(
|
|||
"loongarch64-unknown-linux-gnu" | "loongarch64-unknown-linux-musl" => {
|
||||
common_libs("linux", "loongarch64", &["asan", "lsan", "msan", "tsan"])
|
||||
}
|
||||
"x86_64-apple-darwin" => darwin_libs("osx", &["asan", "lsan", "tsan"]),
|
||||
"x86_64-apple-darwin" => darwin_libs("osx", &["asan", "lsan", "tsan", "rtsan"]),
|
||||
"x86_64-unknown-fuchsia" => common_libs("fuchsia", "x86_64", &["asan"]),
|
||||
"x86_64-apple-ios" => darwin_libs("iossim", &["asan", "tsan"]),
|
||||
"x86_64-apple-ios-macabi" => darwin_libs("osx", &["asan", "lsan", "tsan"]),
|
||||
|
|
@ -1286,9 +1286,11 @@ fn supported_sanitizers(
|
|||
}
|
||||
"x86_64-unknown-illumos" => common_libs("illumos", "x86_64", &["asan"]),
|
||||
"x86_64-pc-solaris" => common_libs("solaris", "x86_64", &["asan"]),
|
||||
"x86_64-unknown-linux-gnu" => {
|
||||
common_libs("linux", "x86_64", &["asan", "dfsan", "lsan", "msan", "safestack", "tsan"])
|
||||
}
|
||||
"x86_64-unknown-linux-gnu" => common_libs(
|
||||
"linux",
|
||||
"x86_64",
|
||||
&["asan", "dfsan", "lsan", "msan", "safestack", "tsan", "rtsan"],
|
||||
),
|
||||
"x86_64-unknown-linux-musl" => {
|
||||
common_libs("linux", "x86_64", &["asan", "lsan", "msan", "tsan"])
|
||||
}
|
||||
|
|
|
|||
|
|
@ -45,7 +45,7 @@ implementation:
|
|||
[marked][sanitizer-attribute] with appropriate LLVM attribute:
|
||||
`SanitizeAddress`, `SanitizeHWAddress`, `SanitizeMemory`, or
|
||||
`SanitizeThread`. By default all functions are instrumented, but this
|
||||
behaviour can be changed with `#[sanitize(xyz = "on|off")]`.
|
||||
behaviour can be changed with `#[sanitize(xyz = "on|off|<other>")]`.
|
||||
|
||||
* The decision whether to perform instrumentation or not is possible only at a
|
||||
function granularity. In the cases were those decision differ between
|
||||
|
|
|
|||
|
|
@ -174,6 +174,7 @@ pub enum Sanitizer {
|
|||
ShadowCallStack,
|
||||
Thread,
|
||||
Hwaddress,
|
||||
Realtime,
|
||||
}
|
||||
|
||||
#[derive(Clone, Copy, Debug, PartialEq)]
|
||||
|
|
|
|||
|
|
@ -165,6 +165,7 @@ pub(crate) const KNOWN_DIRECTIVE_NAMES: &[&str] = &[
|
|||
"needs-sanitizer-leak",
|
||||
"needs-sanitizer-memory",
|
||||
"needs-sanitizer-memtag",
|
||||
"needs-sanitizer-realtime",
|
||||
"needs-sanitizer-safestack",
|
||||
"needs-sanitizer-shadow-call-stack",
|
||||
"needs-sanitizer-support",
|
||||
|
|
|
|||
|
|
@ -69,6 +69,11 @@ pub(super) fn handle_needs(
|
|||
condition: cache.sanitizer_memtag,
|
||||
ignore_reason: "ignored on targets without memory tagging sanitizer",
|
||||
},
|
||||
Need {
|
||||
name: "needs-sanitizer-realtime",
|
||||
condition: cache.sanitizer_realtime,
|
||||
ignore_reason: "ignored on targets without realtime sanitizer",
|
||||
},
|
||||
Need {
|
||||
name: "needs-sanitizer-shadow-call-stack",
|
||||
condition: cache.sanitizer_shadow_call_stack,
|
||||
|
|
@ -320,6 +325,7 @@ pub(super) struct CachedNeedsConditions {
|
|||
sanitizer_thread: bool,
|
||||
sanitizer_hwaddress: bool,
|
||||
sanitizer_memtag: bool,
|
||||
sanitizer_realtime: bool,
|
||||
sanitizer_shadow_call_stack: bool,
|
||||
sanitizer_safestack: bool,
|
||||
xray: bool,
|
||||
|
|
@ -346,6 +352,7 @@ impl CachedNeedsConditions {
|
|||
sanitizer_thread: sanitizers.contains(&Sanitizer::Thread),
|
||||
sanitizer_hwaddress: sanitizers.contains(&Sanitizer::Hwaddress),
|
||||
sanitizer_memtag: sanitizers.contains(&Sanitizer::Memtag),
|
||||
sanitizer_realtime: sanitizers.contains(&Sanitizer::Realtime),
|
||||
sanitizer_shadow_call_stack: sanitizers.contains(&Sanitizer::ShadowCallStack),
|
||||
sanitizer_safestack: sanitizers.contains(&Sanitizer::Safestack),
|
||||
xray: config.target_cfg().xray,
|
||||
|
|
|
|||
|
|
@ -513,7 +513,7 @@ LL | #[sanitize(hwaddress = "on|off")]
|
|||
| ++++++++++++++++++++++
|
||||
LL | #[sanitize(kcfi = "on|off")]
|
||||
| +++++++++++++++++
|
||||
= and 5 other candidates
|
||||
= and 6 other candidates
|
||||
|
||||
error[E0565]: malformed `no_implicit_prelude` attribute input
|
||||
--> $DIR/malformed-attrs.rs:101:1
|
||||
|
|
|
|||
|
|
@ -120,7 +120,7 @@ warning: unexpected `cfg` condition value: `_UNEXPECTED_VALUE`
|
|||
LL | sanitize = "_UNEXPECTED_VALUE",
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
|
||||
= note: expected values for `sanitize` are: `address`, `cfi`, `dataflow`, `hwaddress`, `kcfi`, `kernel-address`, `leak`, `memory`, `memtag`, `safestack`, `shadow-call-stack`, and `thread`
|
||||
= note: expected values for `sanitize` are: `address`, `cfi`, `dataflow`, `hwaddress`, `kcfi`, `kernel-address`, `leak`, `memory`, `memtag`, `realtime`, `safestack`, `shadow-call-stack`, and `thread`
|
||||
= note: see <https://doc.rust-lang.org/nightly/rustc/check-cfg.html> for more information about checking conditional configuration
|
||||
|
||||
warning: unexpected `cfg` condition value: `_UNEXPECTED_VALUE`
|
||||
|
|
|
|||
|
|
@ -19,3 +19,6 @@ fn name_value() {}
|
|||
|
||||
#[sanitize] //~ ERROR malformed `sanitize` attribute input
|
||||
fn just_word() {}
|
||||
|
||||
#[sanitize(realtime = "on")] //~ ERROR malformed `sanitize` attribute input
|
||||
fn wrong_value_realtime() {}
|
||||
|
|
|
|||
|
|
@ -4,7 +4,7 @@ error[E0539]: malformed `sanitize` attribute input
|
|||
LL | #[sanitize(brontosaurus = "off")]
|
||||
| ^^^^^^^^^^^------------^^^^^^^^^^
|
||||
| |
|
||||
| valid arguments are "address", "cfi", "kcfi", "memory", "memtag", "shadow_call_stack", "thread" or "hwaddress"
|
||||
| valid arguments are "address", "cfi", "kcfi", "memory", "memtag", "shadow_call_stack", "thread", "hwaddress" or "realtime"
|
||||
|
|
||||
help: try changing it to one of the following valid forms of the attribute
|
||||
|
|
||||
|
|
@ -20,7 +20,7 @@ LL + #[sanitize(hwaddress = "on|off")]
|
|||
LL - #[sanitize(brontosaurus = "off")]
|
||||
LL + #[sanitize(kcfi = "on|off")]
|
||||
|
|
||||
= and 5 other candidates
|
||||
= and 6 other candidates
|
||||
|
||||
error: multiple `sanitize` attributes
|
||||
--> $DIR/invalid-sanitize.rs:6:1
|
||||
|
|
@ -68,7 +68,7 @@ LL + #[sanitize(hwaddress = "on|off")]
|
|||
LL - #[sanitize(address = "bogus")]
|
||||
LL + #[sanitize(kcfi = "on|off")]
|
||||
|
|
||||
= and 5 other candidates
|
||||
= and 6 other candidates
|
||||
|
||||
error[E0539]: malformed `sanitize` attribute input
|
||||
--> $DIR/invalid-sanitize.rs:17:1
|
||||
|
|
@ -90,7 +90,7 @@ LL + #[sanitize(hwaddress = "on|off")]
|
|||
LL - #[sanitize = "off"]
|
||||
LL + #[sanitize(kcfi = "on|off")]
|
||||
|
|
||||
= and 5 other candidates
|
||||
= and 6 other candidates
|
||||
|
||||
error[E0539]: malformed `sanitize` attribute input
|
||||
--> $DIR/invalid-sanitize.rs:20:1
|
||||
|
|
@ -108,8 +108,32 @@ LL | #[sanitize(hwaddress = "on|off")]
|
|||
| ++++++++++++++++++++++
|
||||
LL | #[sanitize(kcfi = "on|off")]
|
||||
| +++++++++++++++++
|
||||
= and 5 other candidates
|
||||
= and 6 other candidates
|
||||
|
||||
error: aborting due to 6 previous errors
|
||||
error[E0539]: malformed `sanitize` attribute input
|
||||
--> $DIR/invalid-sanitize.rs:23:1
|
||||
|
|
||||
LL | #[sanitize(realtime = "on")]
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^----^^
|
||||
| |
|
||||
| valid arguments are "nonblocking", "blocking" or "caller"
|
||||
|
|
||||
help: try changing it to one of the following valid forms of the attribute
|
||||
|
|
||||
LL - #[sanitize(realtime = "on")]
|
||||
LL + #[sanitize(address = "on|off")]
|
||||
|
|
||||
LL - #[sanitize(realtime = "on")]
|
||||
LL + #[sanitize(cfi = "on|off")]
|
||||
|
|
||||
LL - #[sanitize(realtime = "on")]
|
||||
LL + #[sanitize(hwaddress = "on|off")]
|
||||
|
|
||||
LL - #[sanitize(realtime = "on")]
|
||||
LL + #[sanitize(kcfi = "on|off")]
|
||||
|
|
||||
= and 6 other candidates
|
||||
|
||||
error: aborting due to 7 previous errors
|
||||
|
||||
For more information about this error, try `rustc --explain E0539`.
|
||||
|
|
|
|||
20
tests/ui/sanitizer/realtime-alloc.rs
Normal file
20
tests/ui/sanitizer/realtime-alloc.rs
Normal file
|
|
@ -0,0 +1,20 @@
|
|||
//@ needs-sanitizer-support
|
||||
//@ needs-sanitizer-realtime
|
||||
//
|
||||
//@ compile-flags: -Z sanitizer=realtime
|
||||
//@ exec-env: RTSAN_OPTIONS=abort_on_error=0
|
||||
//
|
||||
//@ run-fail
|
||||
//@ error-pattern: Intercepted call to real-time unsafe function `malloc` in real-time context!
|
||||
//@ ignore-backends: gcc
|
||||
#![feature(sanitize)]
|
||||
|
||||
#[sanitize(realtime = "nonblocking")]
|
||||
fn sanitizer_on() {
|
||||
let mut vec = vec![0, 1, 2];
|
||||
println!("alloc not detected");
|
||||
}
|
||||
|
||||
fn main() {
|
||||
sanitizer_on();
|
||||
}
|
||||
25
tests/ui/sanitizer/realtime-blocking.rs
Normal file
25
tests/ui/sanitizer/realtime-blocking.rs
Normal file
|
|
@ -0,0 +1,25 @@
|
|||
//@ needs-sanitizer-support
|
||||
//@ needs-sanitizer-realtime
|
||||
//
|
||||
//@ compile-flags: -Z sanitizer=realtime
|
||||
//@ exec-env: RTSAN_OPTIONS=abort_on_error=0
|
||||
//
|
||||
//@ run-fail
|
||||
//@ error-pattern: Call to blocking function
|
||||
//@ error-pattern: realtime_blocking::blocking::
|
||||
//@ ignore-backends: gcc
|
||||
#![feature(sanitize)]
|
||||
|
||||
#[sanitize(realtime = "nonblocking")]
|
||||
fn sanitizer_on() {
|
||||
blocking();
|
||||
}
|
||||
|
||||
#[sanitize(realtime = "blocking")]
|
||||
fn blocking() {
|
||||
println!("blocking call not detected");
|
||||
}
|
||||
|
||||
fn main() {
|
||||
sanitizer_on();
|
||||
}
|
||||
28
tests/ui/sanitizer/realtime-caller.rs
Normal file
28
tests/ui/sanitizer/realtime-caller.rs
Normal file
|
|
@ -0,0 +1,28 @@
|
|||
//@ needs-sanitizer-support
|
||||
//@ needs-sanitizer-realtime
|
||||
//
|
||||
//@ compile-flags: -Z sanitizer=realtime
|
||||
//@ exec-env: RTSAN_OPTIONS=abort_on_error=0
|
||||
//
|
||||
//@ run-fail
|
||||
//@ error-pattern: RealtimeSanitizer: blocking-call
|
||||
//@ ignore-backends: gcc
|
||||
#![feature(sanitize)]
|
||||
|
||||
#[sanitize(realtime = "nonblocking")]
|
||||
fn sanitizer_on() {
|
||||
caller();
|
||||
}
|
||||
|
||||
fn caller() {
|
||||
blocking()
|
||||
}
|
||||
|
||||
#[sanitize(realtime = "blocking")]
|
||||
fn blocking() {
|
||||
println!("blocking call not detected");
|
||||
}
|
||||
|
||||
fn main() {
|
||||
sanitizer_on();
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue