diff --git a/compiler/rustc_interface/src/passes.rs b/compiler/rustc_interface/src/passes.rs index ddfec9f886a6a..a0eaa44da0c16 100644 --- a/compiler/rustc_interface/src/passes.rs +++ b/compiler/rustc_interface/src/passes.rs @@ -304,8 +304,7 @@ fn configure_and_expand( resolver.resolve_crate(&krate); - CStore::from_tcx(tcx).report_incompatible_target_modifiers(tcx, &krate); - CStore::from_tcx(tcx).report_incompatible_async_drop_feature(tcx, &krate); + CStore::from_tcx(tcx).report_session_incompatibilities(tcx, &krate); krate } diff --git a/compiler/rustc_metadata/messages.ftl b/compiler/rustc_metadata/messages.ftl index fac7b6c21f60c..349abd29d9058 100644 --- a/compiler/rustc_metadata/messages.ftl +++ b/compiler/rustc_metadata/messages.ftl @@ -153,6 +153,11 @@ metadata_link_ordinal_raw_dylib = metadata_missing_native_library = could not find native static library `{$libname}`, perhaps an -L flag is missing? +metadata_mitigation_less_strict_in_dependency = + your program uses the crate `{$extern_crate}`, that is not protected by `{$mitigation_name}{$mitigation_level}` + .note = recompile `{$extern_crate}` with the mitigation enabled, or use `-Z allow-partial-mitigations={$mitigation_name}` to allow creating an artifact that has the mitigation only partially enabled + .help = it is possible to disable `-Z allow-partial-mitigations={$mitigation_name}` via `-Z allow-partial-mitigations=!{$mitigation_name}` + metadata_multiple_candidates = multiple candidates for `{$flavor}` dependency `{$crate_name}` found diff --git a/compiler/rustc_metadata/src/creader.rs b/compiler/rustc_metadata/src/creader.rs index 4e2e1e21ec6dd..11cae44a14d6c 100644 --- a/compiler/rustc_metadata/src/creader.rs +++ b/compiler/rustc_metadata/src/creader.rs @@ -1,5 +1,6 @@ //! Validates all used crates and extern libraries and loads their metadata +use std::collections::BTreeMap; use std::error::Error; use std::path::Path; use std::str::FromStr; @@ -24,6 +25,7 @@ use rustc_middle::ty::data_structures::IndexSet; use rustc_middle::ty::{TyCtxt, TyCtxtFeed}; use rustc_proc_macro::bridge::client::ProcMacro; use rustc_session::Session; +use rustc_session::config::enforced_mitigations::EnforcedMitigationLevel; use rustc_session::config::{ CrateType, ExtendedTargetModifierInfo, ExternLocation, Externs, OptionsTargetModifiers, TargetModifier, @@ -453,6 +455,12 @@ impl CStore { } } + pub fn report_session_incompatibilities(&self, tcx: TyCtxt<'_>, krate: &Crate) { + self.report_incompatible_target_modifiers(tcx, krate); + self.report_incompatible_enforced_mitigations(tcx, krate); + self.report_incompatible_async_drop_feature(tcx, krate); + } + pub fn report_incompatible_target_modifiers(&self, tcx: TyCtxt<'_>, krate: &Crate) { for flag_name in &tcx.sess.opts.cg.unsafe_allow_abi_mismatch { if !OptionsTargetModifiers::is_target_modifier(flag_name) { @@ -474,6 +482,43 @@ impl CStore { } } + pub fn report_incompatible_enforced_mitigations(&self, tcx: TyCtxt<'_>, krate: &Crate) { + let my_mitigations = tcx.sess.gather_enabled_enforced_mitigations(); + let mut my_mitigations: BTreeMap<_, _> = + my_mitigations.iter().map(|mitigation| (mitigation.kind, mitigation)).collect(); + for skipped_mitigation in tcx.sess.opts.allowed_partial_mitigations(tcx.sess.edition()) { + my_mitigations.remove(&skipped_mitigation); + } + const MAX_ERRORS_PER_MITIGATION: usize = 5; + let mut errors_per_mitigation = BTreeMap::new(); + for (_cnum, data) in self.iter_crate_data() { + if data.is_proc_macro_crate() { + continue; + } + let their_mitigations = data.enforced_mitigations(); + for my_mitigation in my_mitigations.values() { + let their_mitigation = their_mitigations + .iter() + .find(|mitigation| mitigation.kind == my_mitigation.kind) + .map_or(EnforcedMitigationLevel::Enabled(false), |m| m.level); + if their_mitigation < my_mitigation.level { + let errors = errors_per_mitigation.entry(my_mitigation.kind).or_insert(0); + if *errors >= MAX_ERRORS_PER_MITIGATION { + continue; + } + *errors += 1; + + tcx.dcx().emit_err(errors::MitigationLessStrictInDependency { + span: krate.spans.inner_span.shrink_to_lo(), + mitigation_name: my_mitigation.kind.to_string(), + mitigation_level: my_mitigation.level.level_str().to_string(), + extern_crate: data.name(), + }); + } + } + } + } + // Report about async drop types in dependency if async drop feature is disabled pub fn report_incompatible_async_drop_feature(&self, tcx: TyCtxt<'_>, krate: &Crate) { if tcx.features().async_drop() { diff --git a/compiler/rustc_metadata/src/errors.rs b/compiler/rustc_metadata/src/errors.rs index abfd078f7462d..08e5e67b76075 100644 --- a/compiler/rustc_metadata/src/errors.rs +++ b/compiler/rustc_metadata/src/errors.rs @@ -615,3 +615,13 @@ pub struct RawDylibMalformed { #[primary_span] pub span: Span, } + +#[derive(Diagnostic)] +#[diag(metadata_mitigation_less_strict_in_dependency)] +pub struct MitigationLessStrictInDependency { + #[primary_span] + pub span: Span, + pub mitigation_name: String, + pub mitigation_level: String, + pub extern_crate: Symbol, +} diff --git a/compiler/rustc_metadata/src/rmeta/decoder.rs b/compiler/rustc_metadata/src/rmeta/decoder.rs index 5c7de5f3ff846..9424ce5952a84 100644 --- a/compiler/rustc_metadata/src/rmeta/decoder.rs +++ b/compiler/rustc_metadata/src/rmeta/decoder.rs @@ -30,6 +30,7 @@ use rustc_serialize::opaque::MemDecoder; use rustc_serialize::{Decodable, Decoder}; use rustc_session::Session; use rustc_session::config::TargetModifier; +use rustc_session::config::enforced_mitigations::EnforcedMitigation; use rustc_session::cstore::{CrateSource, ExternCrate}; use rustc_span::hygiene::HygieneDecodeContext; use rustc_span::{ @@ -76,9 +77,12 @@ impl MetadataBlob { /// own crate numbers. pub(crate) type CrateNumMap = IndexVec; -/// Target modifiers - abi or exploit mitigations flags +/// Target modifiers - abi or exploit mitigations flags that cause unsoundness when mixed pub(crate) type TargetModifiers = Vec; +/// Enforced Mitigations +pub(crate) type EnforcedMitigations = Vec; + pub(crate) struct CrateMetadata { /// The primary crate data - binary metadata blob. blob: MetadataBlob, @@ -984,6 +988,13 @@ impl CrateRoot { ) -> impl ExactSizeIterator { self.target_modifiers.decode(metadata) } + + pub(crate) fn decode_enforced_mitigations<'a>( + &self, + metadata: &'a MetadataBlob, + ) -> impl ExactSizeIterator { + self.enforced_mitigations.decode(metadata) + } } impl<'a> CrateMetadataRef<'a> { @@ -1929,6 +1940,10 @@ impl CrateMetadata { self.root.decode_target_modifiers(&self.blob).collect() } + pub(crate) fn enforced_mitigations(&self) -> EnforcedMitigations { + self.root.decode_enforced_mitigations(&self.blob).collect() + } + /// Keep `new_extern_crate` if it looks better in diagnostics pub(crate) fn update_extern_crate_diagnostics( &mut self, diff --git a/compiler/rustc_metadata/src/rmeta/encoder.rs b/compiler/rustc_metadata/src/rmeta/encoder.rs index 9fac68039f52c..7cde317fab386 100644 --- a/compiler/rustc_metadata/src/rmeta/encoder.rs +++ b/compiler/rustc_metadata/src/rmeta/encoder.rs @@ -27,6 +27,7 @@ use rustc_middle::ty::codec::TyEncoder; use rustc_middle::ty::fast_reject::{self, TreatParams}; use rustc_middle::{bug, span_bug}; use rustc_serialize::{Decodable, Decoder, Encodable, Encoder, opaque}; +use rustc_session::config::enforced_mitigations::EnforcedMitigation; use rustc_session::config::{CrateType, OptLevel, TargetModifier}; use rustc_span::hygiene::HygieneEncodeContext; use rustc_span::{ @@ -715,6 +716,8 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> { // `SourceFiles` we actually need to encode. let source_map = stat!("source-map", || self.encode_source_map()); let target_modifiers = stat!("target-modifiers", || self.encode_target_modifiers()); + let enforced_mitigations = + stat!("enforced-mitigations", || self.encode_enforced_mitigations()); let root = stat!("final", || { let attrs = tcx.hir_krate_attrs(); @@ -760,6 +763,7 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> { foreign_modules, source_map, target_modifiers, + enforced_mitigations, traits, impls, incoherent_impls, @@ -2087,6 +2091,12 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> { self.lazy_array(tcx.sess.opts.gather_target_modifiers()) } + fn encode_enforced_mitigations(&mut self) -> LazyArray { + empty_proc_macro!(self); + let tcx = self.tcx; + self.lazy_array(tcx.sess.gather_enabled_enforced_mitigations()) + } + fn encode_lib_features(&mut self) -> LazyArray<(Symbol, FeatureStability)> { empty_proc_macro!(self); let tcx = self.tcx; diff --git a/compiler/rustc_metadata/src/rmeta/mod.rs b/compiler/rustc_metadata/src/rmeta/mod.rs index ac042c2ca75de..d11faa252d97e 100644 --- a/compiler/rustc_metadata/src/rmeta/mod.rs +++ b/compiler/rustc_metadata/src/rmeta/mod.rs @@ -34,6 +34,7 @@ use rustc_middle::ty::fast_reject::SimplifiedType; use rustc_middle::ty::{self, Ty, TyCtxt, UnusedGenericParams}; use rustc_middle::util::Providers; use rustc_serialize::opaque::FileEncoder; +use rustc_session::config::enforced_mitigations::EnforcedMitigation; use rustc_session::config::{SymbolManglingVersion, TargetModifier}; use rustc_session::cstore::{CrateDepKind, ForeignModule, LinkagePreference, NativeLib}; use rustc_span::edition::Edition; @@ -283,6 +284,7 @@ pub(crate) struct CrateRoot { source_map: LazyTable>>, target_modifiers: LazyArray, + enforced_mitigations: LazyArray, compiler_builtins: bool, needs_allocator: bool, diff --git a/compiler/rustc_metadata/src/rmeta/parameterized.rs b/compiler/rustc_metadata/src/rmeta/parameterized.rs index d8bae5a54e313..419fa9ef8791e 100644 --- a/compiler/rustc_metadata/src/rmeta/parameterized.rs +++ b/compiler/rustc_metadata/src/rmeta/parameterized.rs @@ -117,6 +117,7 @@ trivially_parameterized_over_tcx! { rustc_middle::ty::adjustment::CoerceUnsizedInfo, rustc_middle::ty::fast_reject::SimplifiedType, rustc_session::config::TargetModifier, + rustc_session::config::enforced_mitigations::EnforcedMitigation, rustc_session::cstore::ForeignModule, rustc_session::cstore::LinkagePreference, rustc_session::cstore::NativeLib, diff --git a/compiler/rustc_session/src/options.rs b/compiler/rustc_session/src/options.rs index 7c7e9118d590f..900a9fc468d26 100644 --- a/compiler/rustc_session/src/options.rs +++ b/compiler/rustc_session/src/options.rs @@ -19,6 +19,7 @@ use rustc_target::spec::{ TargetTuple, TlsModel, }; +use crate::config::enforced_mitigations::MitigationEnablement; use crate::config::*; use crate::search_paths::SearchPath; use crate::utils::NativeLib; @@ -83,6 +84,8 @@ pub struct TargetModifier { pub value_name: String, } +pub mod enforced_mitigations; + mod target_modifier_consistency_check { use super::*; pub(super) fn sanitizer(l: &TargetModifier, r: Option<&TargetModifier>) -> bool { @@ -880,12 +883,15 @@ mod desc { pub(crate) const parse_mir_include_spans: &str = "either a boolean (`yes`, `no`, `on`, `off`, etc), or `nll` (default: `nll`)"; pub(crate) const parse_align: &str = "a number that is a power of 2 between 1 and 2^29"; + pub(crate) const parse_allow_partial_mitigations: &str = + super::enforced_mitigations::EnforcedMitigationKind::KINDS; } pub mod parse { use std::str::FromStr; pub(crate) use super::*; + use crate::config::enforced_mitigations::MitigationEnablement; pub(crate) const MAX_THREADS_CAP: usize = 256; /// This is for boolean options that don't take a value, and are true simply @@ -2062,6 +2068,26 @@ pub mod parse { true } + + pub(crate) fn parse_allow_partial_mitigations( + slot: &mut Vec, + v: Option<&str>, + ) -> bool { + match v { + Some(s) => { + for sub in s.split(',') { + let (sub, enabled) = + if sub.starts_with('!') { (&sub[1..], false) } else { (sub, true) }; + match sub.parse() { + Ok(kind) => slot.push(MitigationEnablement { kind, enabled }), + Err(_) => return false, + } + } + true + } + None => false, + } + } } options! { @@ -2222,6 +2248,8 @@ options! { // tidy-alphabetical-start allow_features: Option> = (None, parse_opt_comma_list, [TRACKED], "only allow the listed language features to be enabled in code (comma separated)"), + allow_partial_mitigations: Vec = (Vec::new(), parse_allow_partial_mitigations, [UNTRACKED], + "Allow mitigations not enabled for all dependency crates (comma separated list)"), always_encode_mir: bool = (false, parse_bool, [TRACKED], "encode MIR of all functions into the crate metadata (default: no)"), annotate_moves: AnnotateMoves = (AnnotateMoves::Disabled, parse_annotate_moves, [TRACKED], diff --git a/compiler/rustc_session/src/options/enforced_mitigations.rs b/compiler/rustc_session/src/options/enforced_mitigations.rs new file mode 100644 index 0000000000000..8a0f2b10125d0 --- /dev/null +++ b/compiler/rustc_session/src/options/enforced_mitigations.rs @@ -0,0 +1,182 @@ +use std::collections::BTreeSet; +use std::str::FromStr; + +use rustc_macros::{Decodable, Encodable}; +use rustc_span::edition::Edition; +use rustc_target::spec::StackProtector; + +use crate::Session; +use crate::config::Options; +use crate::options::CFGuard; + +#[derive(Copy, Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Encodable, Decodable)] +pub enum EnforcedMitigationLevel { + // Enabled(false) should be the bottom of the Ord hierarchy + Enabled(bool), + StackProtector(StackProtector), +} + +impl EnforcedMitigationLevel { + pub fn level_str(&self) -> &'static str { + match self { + EnforcedMitigationLevel::StackProtector(StackProtector::All) => "=all", + EnforcedMitigationLevel::StackProtector(StackProtector::Basic) => "=basic", + EnforcedMitigationLevel::StackProtector(StackProtector::Strong) => "=strong", + // currently `=disabled` should not appear + EnforcedMitigationLevel::Enabled(false) => "=disabled", + EnforcedMitigationLevel::StackProtector(StackProtector::None) + | EnforcedMitigationLevel::Enabled(true) => "", + } + } +} + +impl std::fmt::Display for EnforcedMitigationLevel { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + match self { + EnforcedMitigationLevel::StackProtector(StackProtector::All) => { + write!(f, "all") + } + EnforcedMitigationLevel::StackProtector(StackProtector::Basic) => { + write!(f, "basic") + } + EnforcedMitigationLevel::StackProtector(StackProtector::Strong) => { + write!(f, "strong") + } + EnforcedMitigationLevel::Enabled(true) => { + write!(f, "enabled") + } + EnforcedMitigationLevel::StackProtector(StackProtector::None) + | EnforcedMitigationLevel::Enabled(false) => { + write!(f, "disabled") + } + } + } +} + +impl From for EnforcedMitigationLevel { + fn from(value: bool) -> Self { + EnforcedMitigationLevel::Enabled(value) + } +} + +impl From for EnforcedMitigationLevel { + fn from(value: StackProtector) -> Self { + EnforcedMitigationLevel::StackProtector(value) + } +} + +pub struct EnforcedMitigationKindParseError; + +#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash, PartialOrd, Ord, Encodable, Decodable)] +pub struct MitigationEnablement { + pub kind: EnforcedMitigationKind, + pub enabled: bool, +} + +macro_rules! intersperse { + ($sep:expr, ($first:expr $(, $rest:expr)* $(,)?)) => { + concat!($first $(, $sep, $rest)*) + }; +} + +macro_rules! enforced_mitigations { + ([$self:ident] enum $kind:ident {$(($name:ident, $text:expr, $since:ident, $code:expr)),*}) => { + #[derive(Copy, Clone, Debug, PartialEq, Eq, Hash, PartialOrd, Ord, Encodable, Decodable)] + pub enum EnforcedMitigationKind { + $($name),* + } + + impl std::fmt::Display for EnforcedMitigationKind { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + match self { + $(EnforcedMitigationKind::$name => write!(f, $text)),* + } + } + } + + impl EnforcedMitigationKind { + pub(crate) const KINDS: &'static str = concat!("comma-separated list of mitigation kinds (available: ", + intersperse!(", ", ($(concat!("`", $text, "`")),*)), ")"); + } + + impl FromStr for EnforcedMitigationKind { + type Err = EnforcedMitigationKindParseError; + + fn from_str(v: &str) -> Result { + match v { + $($text => Ok(EnforcedMitigationKind::$name)),* + , + _ => Err(EnforcedMitigationKindParseError), + } + } + } + + #[allow(unused)] + impl EnforcedMitigationKind { + pub fn enforced_since(&self) -> Edition { + match self { + // Should change the enforced-since edition of StackProtector to 2015 + // (all editions) when `-C stack-protector` is stabilized. + $(EnforcedMitigationKind::$name => Edition::$since),* + } + } + } + + impl Options { + pub fn all_enforced_mitigations(&self) -> impl Iterator { + [$(EnforcedMitigationKind::$name),*].into_iter() + } + } + + impl Session { + pub fn gather_enabled_enforced_mitigations(&$self) -> Vec { + let mut mitigations = [ + $( + EnforcedMitigation { + kind: EnforcedMitigationKind::$name, + level: From::from($code), + } + ),* + ]; + mitigations.sort(); + mitigations.into_iter().collect() + } + } + } +} + +enforced_mitigations! { + [self] + enum EnforcedMitigationKind { + (StackProtector, "stack-protector", EditionFuture, self.stack_protector()), + (ControlFlowGuard, "control-flow-guard", EditionFuture, self.opts.cg.control_flow_guard == CFGuard::Checks) + } +} + +/// Enforced mitigations, see [RFC 3855](https://github.com/rust-lang/rfcs/pull/3855) +#[derive(Copy, Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Encodable, Decodable)] +pub struct EnforcedMitigation { + pub kind: EnforcedMitigationKind, + pub level: EnforcedMitigationLevel, +} + +impl Options { + // Return the list of mitigations that are allowed to be partial + pub fn allowed_partial_mitigations( + &self, + edition: Edition, + ) -> impl Iterator { + let mut result: BTreeSet<_> = self + .all_enforced_mitigations() + .filter(|mitigation| mitigation.enforced_since() > edition) + .collect(); + for mitigation in &self.unstable_opts.allow_partial_mitigations { + if mitigation.enabled { + result.insert(mitigation.kind); + } else { + result.remove(&mitigation.kind); + } + } + result.into_iter() + } +} diff --git a/compiler/rustc_target/src/spec/mod.rs b/compiler/rustc_target/src/spec/mod.rs index 2b1c7174fb15d..06f5c246a9f4e 100644 --- a/compiler/rustc_target/src/spec/mod.rs +++ b/compiler/rustc_target/src/spec/mod.rs @@ -1336,6 +1336,7 @@ impl FramePointer { crate::target_spec_enum! { /// Controls use of stack canaries. + #[derive(Encodable, Decodable, HashStable_Generic)] pub enum StackProtector { /// Disable stack canary generation. None = "none", diff --git a/tests/ui/allow-partial-mitigations/err-allow-partial-mitigations-current-edition.rs b/tests/ui/allow-partial-mitigations/err-allow-partial-mitigations-current-edition.rs new file mode 100644 index 0000000000000..243f7916d5f70 --- /dev/null +++ b/tests/ui/allow-partial-mitigations/err-allow-partial-mitigations-current-edition.rs @@ -0,0 +1,17 @@ +// ignore-tidy-linelength +//@ check-fail +//@ ignore-nvptx64 stack protector is not supported +//@ ignore-wasm32-unknown-unknown stack protector is not supported +//@ edition: 2024 +//@ compile-flags: -Z allow-partial-mitigations=!control-flow-guard -C control-flow-guard=on + +// check that in edition 2024, it is still possible to explicitly +// disallow partial mitigations (in edition=future, they are +// disallowed by default) + +fn main() {} +//~^ ERROR that is not protected by +//~| ERROR that is not protected by +//~| ERROR that is not protected by +//~| ERROR that is not protected by +//~| ERROR that is not protected by diff --git a/tests/ui/allow-partial-mitigations/err-allow-partial-mitigations-current-edition.stderr b/tests/ui/allow-partial-mitigations/err-allow-partial-mitigations-current-edition.stderr new file mode 100644 index 0000000000000..a5a7414c3f293 --- /dev/null +++ b/tests/ui/allow-partial-mitigations/err-allow-partial-mitigations-current-edition.stderr @@ -0,0 +1,32 @@ +error: your program uses the crate `std`, that is not protected by `control-flow-guard` + --> $DIR/err-allow-partial-mitigations-current-edition.rs:12:1 + | +LL | fn main() {} + | ^ + +error: your program uses the crate `core`, that is not protected by `control-flow-guard` + --> $DIR/err-allow-partial-mitigations-current-edition.rs:12:1 + | +LL | fn main() {} + | ^ + +error: your program uses the crate `alloc`, that is not protected by `control-flow-guard` + --> $DIR/err-allow-partial-mitigations-current-edition.rs:12:1 + | +LL | fn main() {} + | ^ + +error: your program uses the crate `compiler_builtins`, that is not protected by `control-flow-guard` + --> $DIR/err-allow-partial-mitigations-current-edition.rs:12:1 + | +LL | fn main() {} + | ^ + +error: your program uses the crate `libc`, that is not protected by `control-flow-guard` + --> $DIR/err-allow-partial-mitigations-current-edition.rs:12:1 + | +LL | fn main() {} + | ^ + +error: aborting due to 5 previous errors + diff --git a/tests/ui/allow-partial-mitigations/err-allow-partial-mitigations.both.stderr b/tests/ui/allow-partial-mitigations/err-allow-partial-mitigations.both.stderr new file mode 100644 index 0000000000000..96950a3c92684 --- /dev/null +++ b/tests/ui/allow-partial-mitigations/err-allow-partial-mitigations.both.stderr @@ -0,0 +1,62 @@ +error: your program uses the crate `std`, that is not protected by `stack-protector=all` + --> $DIR/err-allow-partial-mitigations.rs:13:1 + | +LL | fn main() {} + | ^ + +error: your program uses the crate `std`, that is not protected by `control-flow-guard` + --> $DIR/err-allow-partial-mitigations.rs:13:1 + | +LL | fn main() {} + | ^ + +error: your program uses the crate `core`, that is not protected by `stack-protector=all` + --> $DIR/err-allow-partial-mitigations.rs:13:1 + | +LL | fn main() {} + | ^ + +error: your program uses the crate `core`, that is not protected by `control-flow-guard` + --> $DIR/err-allow-partial-mitigations.rs:13:1 + | +LL | fn main() {} + | ^ + +error: your program uses the crate `alloc`, that is not protected by `stack-protector=all` + --> $DIR/err-allow-partial-mitigations.rs:13:1 + | +LL | fn main() {} + | ^ + +error: your program uses the crate `alloc`, that is not protected by `control-flow-guard` + --> $DIR/err-allow-partial-mitigations.rs:13:1 + | +LL | fn main() {} + | ^ + +error: your program uses the crate `compiler_builtins`, that is not protected by `stack-protector=all` + --> $DIR/err-allow-partial-mitigations.rs:13:1 + | +LL | fn main() {} + | ^ + +error: your program uses the crate `compiler_builtins`, that is not protected by `control-flow-guard` + --> $DIR/err-allow-partial-mitigations.rs:13:1 + | +LL | fn main() {} + | ^ + +error: your program uses the crate `libc`, that is not protected by `stack-protector=all` + --> $DIR/err-allow-partial-mitigations.rs:13:1 + | +LL | fn main() {} + | ^ + +error: your program uses the crate `libc`, that is not protected by `control-flow-guard` + --> $DIR/err-allow-partial-mitigations.rs:13:1 + | +LL | fn main() {} + | ^ + +error: aborting due to 10 previous errors + diff --git a/tests/ui/allow-partial-mitigations/err-allow-partial-mitigations.disable.stderr b/tests/ui/allow-partial-mitigations/err-allow-partial-mitigations.disable.stderr new file mode 100644 index 0000000000000..5dc6c1e4cd757 --- /dev/null +++ b/tests/ui/allow-partial-mitigations/err-allow-partial-mitigations.disable.stderr @@ -0,0 +1,32 @@ +error: your program uses the crate `std`, that is not protected by `stack-protector=all` + --> $DIR/err-allow-partial-mitigations.rs:13:1 + | +LL | fn main() {} + | ^ + +error: your program uses the crate `core`, that is not protected by `stack-protector=all` + --> $DIR/err-allow-partial-mitigations.rs:13:1 + | +LL | fn main() {} + | ^ + +error: your program uses the crate `alloc`, that is not protected by `stack-protector=all` + --> $DIR/err-allow-partial-mitigations.rs:13:1 + | +LL | fn main() {} + | ^ + +error: your program uses the crate `compiler_builtins`, that is not protected by `stack-protector=all` + --> $DIR/err-allow-partial-mitigations.rs:13:1 + | +LL | fn main() {} + | ^ + +error: your program uses the crate `libc`, that is not protected by `stack-protector=all` + --> $DIR/err-allow-partial-mitigations.rs:13:1 + | +LL | fn main() {} + | ^ + +error: aborting due to 5 previous errors + diff --git a/tests/ui/allow-partial-mitigations/err-allow-partial-mitigations.enable-disable.stderr b/tests/ui/allow-partial-mitigations/err-allow-partial-mitigations.enable-disable.stderr new file mode 100644 index 0000000000000..5dc6c1e4cd757 --- /dev/null +++ b/tests/ui/allow-partial-mitigations/err-allow-partial-mitigations.enable-disable.stderr @@ -0,0 +1,32 @@ +error: your program uses the crate `std`, that is not protected by `stack-protector=all` + --> $DIR/err-allow-partial-mitigations.rs:13:1 + | +LL | fn main() {} + | ^ + +error: your program uses the crate `core`, that is not protected by `stack-protector=all` + --> $DIR/err-allow-partial-mitigations.rs:13:1 + | +LL | fn main() {} + | ^ + +error: your program uses the crate `alloc`, that is not protected by `stack-protector=all` + --> $DIR/err-allow-partial-mitigations.rs:13:1 + | +LL | fn main() {} + | ^ + +error: your program uses the crate `compiler_builtins`, that is not protected by `stack-protector=all` + --> $DIR/err-allow-partial-mitigations.rs:13:1 + | +LL | fn main() {} + | ^ + +error: your program uses the crate `libc`, that is not protected by `stack-protector=all` + --> $DIR/err-allow-partial-mitigations.rs:13:1 + | +LL | fn main() {} + | ^ + +error: aborting due to 5 previous errors + diff --git a/tests/ui/allow-partial-mitigations/err-allow-partial-mitigations.rs b/tests/ui/allow-partial-mitigations/err-allow-partial-mitigations.rs new file mode 100644 index 0000000000000..8509875e43836 --- /dev/null +++ b/tests/ui/allow-partial-mitigations/err-allow-partial-mitigations.rs @@ -0,0 +1,43 @@ +// ignore-tidy-linelength +//@ revisions: sp both disable enable-disable wrong-enable +//@ check-fail +//@ ignore-nvptx64 stack protector is not supported +//@ ignore-wasm32-unknown-unknown stack protector is not supported +//@ edition:future +//@ [both] compile-flags: -Z unstable-options -C control-flow-guard=on -Z stack-protector=all +//@ [sp] compile-flags: -Z unstable-options -Z stack-protector=all +//@ [disable] compile-flags: -Z unstable-options -Z allow-partial-mitigations=!stack-protector -Z stack-protector=all +//@ [enable-disable] compile-flags: -Z unstable-options -Z allow-partial-mitigations=stack-protector -Z allow-partial-mitigations=!stack-protector -Z stack-protector=all +//@ [wrong-enable] compile-flags: -Z unstable-options -Z allow-partial-mitigations=control-flow-guard -Z stack-protector=all + +fn main() {} +//[both]~^ ERROR that is not protected by +//[both]~| ERROR that is not protected by +//[both]~| ERROR that is not protected by +//[both]~| ERROR that is not protected by +//[both]~| ERROR that is not protected by +//[both]~| ERROR that is not protected by +//[both]~| ERROR that is not protected by +//[both]~| ERROR that is not protected by +//[both]~| ERROR that is not protected by +//[both]~| ERROR that is not protected by +//[sp]~^^^^^^^^^^^ ERROR that is not protected by +//[sp]~| ERROR that is not protected by +//[sp]~| ERROR that is not protected by +//[sp]~| ERROR that is not protected by +//[sp]~| ERROR that is not protected by +//[disable]~^^^^^^^^^^^^^^^^ ERROR that is not protected by +//[disable]~| ERROR that is not protected by +//[disable]~| ERROR that is not protected by +//[disable]~| ERROR that is not protected by +//[disable]~| ERROR that is not protected by +//[enable-disable]~^^^^^^^^^^^^^^^^^^^^^ ERROR that is not protected by +//[enable-disable]~| ERROR that is not protected by +//[enable-disable]~| ERROR that is not protected by +//[enable-disable]~| ERROR that is not protected by +//[enable-disable]~| ERROR that is not protected by +//[wrong-enable]~^^^^^^^^^^^^^^^^^^^^^^^^^^ ERROR that is not protected by +//[wrong-enable]~| ERROR that is not protected by +//[wrong-enable]~| ERROR that is not protected by +//[wrong-enable]~| ERROR that is not protected by +//[wrong-enable]~| ERROR that is not protected by diff --git a/tests/ui/allow-partial-mitigations/err-allow-partial-mitigations.sp.stderr b/tests/ui/allow-partial-mitigations/err-allow-partial-mitigations.sp.stderr new file mode 100644 index 0000000000000..5dc6c1e4cd757 --- /dev/null +++ b/tests/ui/allow-partial-mitigations/err-allow-partial-mitigations.sp.stderr @@ -0,0 +1,32 @@ +error: your program uses the crate `std`, that is not protected by `stack-protector=all` + --> $DIR/err-allow-partial-mitigations.rs:13:1 + | +LL | fn main() {} + | ^ + +error: your program uses the crate `core`, that is not protected by `stack-protector=all` + --> $DIR/err-allow-partial-mitigations.rs:13:1 + | +LL | fn main() {} + | ^ + +error: your program uses the crate `alloc`, that is not protected by `stack-protector=all` + --> $DIR/err-allow-partial-mitigations.rs:13:1 + | +LL | fn main() {} + | ^ + +error: your program uses the crate `compiler_builtins`, that is not protected by `stack-protector=all` + --> $DIR/err-allow-partial-mitigations.rs:13:1 + | +LL | fn main() {} + | ^ + +error: your program uses the crate `libc`, that is not protected by `stack-protector=all` + --> $DIR/err-allow-partial-mitigations.rs:13:1 + | +LL | fn main() {} + | ^ + +error: aborting due to 5 previous errors + diff --git a/tests/ui/allow-partial-mitigations/err-allow-partial-mitigations.wrong-enable.stderr b/tests/ui/allow-partial-mitigations/err-allow-partial-mitigations.wrong-enable.stderr new file mode 100644 index 0000000000000..5dc6c1e4cd757 --- /dev/null +++ b/tests/ui/allow-partial-mitigations/err-allow-partial-mitigations.wrong-enable.stderr @@ -0,0 +1,32 @@ +error: your program uses the crate `std`, that is not protected by `stack-protector=all` + --> $DIR/err-allow-partial-mitigations.rs:13:1 + | +LL | fn main() {} + | ^ + +error: your program uses the crate `core`, that is not protected by `stack-protector=all` + --> $DIR/err-allow-partial-mitigations.rs:13:1 + | +LL | fn main() {} + | ^ + +error: your program uses the crate `alloc`, that is not protected by `stack-protector=all` + --> $DIR/err-allow-partial-mitigations.rs:13:1 + | +LL | fn main() {} + | ^ + +error: your program uses the crate `compiler_builtins`, that is not protected by `stack-protector=all` + --> $DIR/err-allow-partial-mitigations.rs:13:1 + | +LL | fn main() {} + | ^ + +error: your program uses the crate `libc`, that is not protected by `stack-protector=all` + --> $DIR/err-allow-partial-mitigations.rs:13:1 + | +LL | fn main() {} + | ^ + +error: aborting due to 5 previous errors + diff --git a/tests/ui/allow-partial-mitigations/ok-allow-partial-mitigations-minicore.rs b/tests/ui/allow-partial-mitigations/ok-allow-partial-mitigations-minicore.rs new file mode 100644 index 0000000000000..16eecd455dbe0 --- /dev/null +++ b/tests/ui/allow-partial-mitigations/ok-allow-partial-mitigations-minicore.rs @@ -0,0 +1,18 @@ +// ignore-tidy-linelength +//@ check-pass +//@ add-minicore +//@ edition:future +//@ revisions: default deny +//@[default] compile-flags: -Z unstable-options -Z stack-protector=all +//@[deny] compile-flags: -Z allow-partial-mitigations=!stack-protector -Z unstable-options -Z stack-protector=all + +// ^ enables stack-protector for both minicore and this crate + +#![crate_type = "lib"] +#![feature(no_core)] +#![no_std] +#![no_core] + +extern crate minicore; + +pub fn foo() {} diff --git a/tests/ui/allow-partial-mitigations/ok-allow-partial-mitigations.rs b/tests/ui/allow-partial-mitigations/ok-allow-partial-mitigations.rs new file mode 100644 index 0000000000000..c0ec555305841 --- /dev/null +++ b/tests/ui/allow-partial-mitigations/ok-allow-partial-mitigations.rs @@ -0,0 +1,11 @@ +// ignore-tidy-linelength +//@ revisions: sp both disable-enable +//@ check-pass +//@ edition:future +//@ ignore-nvptx64 stack protector is not supported +//@ ignore-wasm32-unknown-unknown stack protector is not supported +//@ [both] compile-flags: -Z unstable-options -Z allow-partial-mitigations=stack-protector,control-flow-guard -C control-flow-guard=on -Z stack-protector=all +//@ [sp] compile-flags: -Z unstable-options -Z allow-partial-mitigations=stack-protector -Z stack-protector=all +//@ [disable-enable] compile-flags: -Z unstable-options -Z allow-partial-mitigations=!stack-protector -Z allow-partial-mitigations=stack-protector -Z stack-protector=all + +fn main() {}