Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
61 changes: 61 additions & 0 deletions compiler/rustc_lint_defs/src/builtin.rs
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,7 @@ pub mod hardwired {
NON_EXHAUSTIVE_OMITTED_PATTERNS,
OUT_OF_SCOPE_MACRO_CALLS,
OVERLAPPING_RANGE_ENDPOINTS,
PARTIAL_STACK_PROTECTOR,
PATTERNS_IN_FNS_WITHOUT_BODY,
PRIVATE_BOUNDS,
PRIVATE_INTERFACES,
Expand Down Expand Up @@ -5858,3 +5859,63 @@ declare_lint! {
"`repr(C, align)` types nested inside `repr(C, packed)` types \
do not always have a C-compatible layout",
}

declare_lint! {
/// The `partial_stack_protector` lint detects uses of the `-Z stack-protector`
/// compile flag to build a program that contains crates that are not protected
/// by stack-protector, or protected by a weaker level of it than the crate
/// you are compiling.
///
/// ### Example
///
/// ```text
/// rustc -Z stack-protector=all
/// ```
///
/// ```rust,ignore (needs command line option)
/// fn main() {}
/// ```
///
/// This will produce:
///
/// ```text
/// warning: your program uses the crate `std`, that is not compiled with `stack-protector=all` enabled
/// |
/// = note: recompile `std` with `stack-protector=all` enabled, or use `-Z allow-partial-mitigations=stack-protector` to allow creating an artifact that has the mitigation partially enabled
/// = help: it is possible to disable `-Z allow-partial-mitigations=stack-protector` via `-Z deny-partial-mitigations=stack-protector`
/// = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
/// = note: for more information, see issue #154613 <https://github.com/rust-lang/rust/issues/154613>
/// = note: `#[warn(partial_stack_protector)]` (part of `#[warn(future_incompatible)]`) on by default
/// ```
///
/// ### Explanation
///
/// Using the `-Z stack-protector` flag on only part of a compiled object
/// will lead to a compiled program that is not fully protected by stack-protector,
/// which is a security risk. This was previously accepted and used in practice,
/// and is now being phased out. This is a [future-incompatible] lint to transition this
/// to a hard error in the future. See [issue #154613] for more details.
///
/// If you intentionally want to use the `-Z stack-protector` flag for only a part
/// of your compiled program, you can allow it in a future-compatible way
/// using the `-Z allow-partial-mitigations=stack-protector` flag, which must be
/// passed *after* the `-Z stack-protector` flag in the command line, for example:
///
/// ```text
/// rustc -Z stack-protector=all -Z allow-partial-mitigations=stack-protector
/// ```
///
/// The order dependency is by design, see the [RFC 3855] for details.
///
/// [issue #154613]: https://github.com/rust-lang/rust/issues/154613
/// [RFC 3855]: https://github.com/rust-lang/rfcs/blob/master/text/3855-mitigation-enforcement.md
/// [future-incompatible]: ../index.md#future-incompatible-lints
pub PARTIAL_STACK_PROTECTOR,
Warn,
"partial use of stack-protector that was previously accepted and used in practice",
@future_incompatible = FutureIncompatibleInfo {
reason: fcw!(FutureReleaseError #154613),
report_in_deps: false,
};
crate_level_only
}
17 changes: 13 additions & 4 deletions compiler/rustc_metadata/src/creader.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,12 +18,14 @@ use rustc_hir::def_id::{CrateNum, LOCAL_CRATE, LocalDefId, StableCrateId};
use rustc_hir::definitions::Definitions;
use rustc_index::IndexVec;
use rustc_lint_defs as lint;
use rustc_lint_defs::builtin::UNUSED_CRATE_DEPENDENCIES;
use rustc_lint_defs::builtin::{PARTIAL_STACK_PROTECTOR, UNUSED_CRATE_DEPENDENCIES};
use rustc_middle::ty::data_structures::IndexSet;
use rustc_middle::ty::{TyCtxt, TyCtxtFeed};
use rustc_proc_macro::bridge::client::Client as ProcMacroClient;
use rustc_session::Session;
use rustc_session::config::mitigation_coverage::DeniedPartialMitigationLevel;
use rustc_session::config::mitigation_coverage::{
DeniedPartialMitigationKind, DeniedPartialMitigationLevel,
};
use rustc_session::config::{
ExtendedTargetModifierInfo, ExternLocation, Externs, OptionsTargetModifiers, TargetModifier,
};
Expand Down Expand Up @@ -499,11 +501,18 @@ impl CStore {
}
*errors += 1;

tcx.dcx().emit_err(diagnostics::MitigationLessStrictInDependency {
let diagnostic = diagnostics::MitigationLessStrictInDependency {
mitigation_name: my_mitigation.kind.to_string(),
mitigation_level: my_mitigation.level.level_str().to_string(),
extern_crate: data.name(),
});
};
if my_mitigation.kind == DeniedPartialMitigationKind::StackProtector {
// make stack-protector only a forward-compat warning since it was
// pretty widely used
tcx.sess.psess.buffer_crate_lint(PARTIAL_STACK_PROTECTOR, diagnostic);
} else {
tcx.dcx().emit_err(diagnostic);
}
}
}
}
Expand Down
7 changes: 2 additions & 5 deletions compiler/rustc_session/src/config/cfg.rs
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,6 @@ use std::hash::Hash;
use std::iter;

use rustc_abi::Align;
use rustc_ast::ast;
use rustc_data_structures::fx::{FxHashMap, FxHashSet, FxIndexSet};
use rustc_lint_defs::builtin::EXPLICIT_BUILTIN_CFGS_IN_FLAGS;
use rustc_span::{Symbol, sym};
Expand Down Expand Up @@ -101,11 +100,9 @@ pub(crate) fn disallow_cfgs(sess: &Session, user_cfgs: &Cfg) {
} else {
format!("{}", cfg_name)
};
sess.psess.opt_span_buffer_lint(
sess.psess.buffer_crate_lint(
EXPLICIT_BUILTIN_CFGS_IN_FLAGS,
None,
ast::CRATE_NODE_ID,
diagnostics::UnexpectedBuiltinCfg { cfg, cfg_name, controlled_by }.into(),
diagnostics::UnexpectedBuiltinCfg { cfg, cfg_name, controlled_by },
)
};

Expand Down
4 changes: 3 additions & 1 deletion compiler/rustc_session/src/options/mitigation_coverage.rs
Original file line number Diff line number Diff line change
Expand Up @@ -203,7 +203,9 @@ denied_partial_mitigations! {
enum DeniedPartialMitigationKind {
// The mitigation name should match the option name in rustc_session::options,
// to allow for resetting the mitigation
(StackProtector, "stack-protector", EditionFuture, self.stack_protector()),

// stack-protector is an unstable option, so it can be denied-partial
(StackProtector, "stack-protector", Edition2015, self.stack_protector()),
(ControlFlowGuard, "control-flow-guard", EditionFuture, self.opts.cg.control_flow_guard == CFGuard::Checks)
}
}
Expand Down
11 changes: 11 additions & 0 deletions compiler/rustc_session/src/parse.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@

use std::sync::Arc;

use rustc_ast::ast;
use rustc_ast::attr::AttrIdGenerator;
use rustc_ast::node_id::NodeId;
use rustc_data_structures::fx::{FxHashMap, FxIndexMap};
Expand Down Expand Up @@ -147,6 +148,16 @@ impl ParseSess {
self.opt_span_buffer_lint(lint, Some(span.into()), node_id, diagnostic.into())
}

/// Buffer a crate-level lint. This is used for lints that are associated with command-line
/// arguments and dependency structure.
pub fn buffer_crate_lint(
&self,
lint: &'static Lint,
diagnostic: impl Into<DecorateDiagCompat>,
) {
self.opt_span_buffer_lint(lint, None, ast::CRATE_NODE_ID, diagnostic.into())
}

pub fn dyn_buffer_lint<
F: for<'a> FnOnce(DiagCtxtHandle<'a>, Level) -> Diag<'a> + DynSync + DynSend + 'static,
>(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
//@ [strong] compile-flags: -Z stack-protector=strong
//@ [basic] compile-flags: -Z stack-protector=basic
//@ [none] compile-flags: -Z stack-protector=none
//@ compile-flags: -C opt-level=2 -Z merge-functions=disabled
//@ compile-flags: -C opt-level=2 -Z merge-functions=disabled -Z allow-partial-mitigations=stack-protector

#![crate_type = "lib"]
#![allow(internal_features)]
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
//@ [all] compile-flags: -Z stack-protector=all
//@ [strong] compile-flags: -Z stack-protector=strong
//@ [none] compile-flags: -Z stack-protector=none
//@ compile-flags: -C opt-level=2 -Z merge-functions=disabled
//@ compile-flags: -C opt-level=2 -Z merge-functions=disabled -Z allow-partial-mitigations=stack-protector
//@ min-llvm-version: 23

#![crate_type = "lib"]
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
//@ [all] compile-flags: -Z stack-protector=all
//@ [strong] compile-flags: -Z stack-protector=strong
//@ [none] compile-flags: -Z stack-protector=none
//@ compile-flags: -C opt-level=2 -Z merge-functions=disabled
//@ compile-flags: -Z allow-partial-mitigations=stack-protector -C opt-level=2 -Z merge-functions=disabled

#![crate_type = "lib"]
#![allow(internal_features)]
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
//@ [strong] compile-flags: -Z stack-protector=strong
//@ [basic] compile-flags: -Z stack-protector=basic
//@ [none] compile-flags: -Z stack-protector=none
//@ compile-flags: -C opt-level=2 -Z merge-functions=disabled -Cpanic=abort -Cdebuginfo=1
//@ compile-flags: -Z allow-partial-mitigations=stack-protector -C opt-level=2 -Z merge-functions=disabled -Cpanic=abort -Cdebuginfo=1

#![crate_type = "lib"]
#![allow(internal_features)]
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
//@ [all] compile-flags: -Z stack-protector=all
//@ [strong] compile-flags: -Z stack-protector=strong
//@ [none] compile-flags: -Z stack-protector=none
//@ compile-flags: -C opt-level=2 -Z merge-functions=disabled
//@ compile-flags: -Z allow-partial-mitigations=stack-protector -C opt-level=2 -Z merge-functions=disabled

#![crate_type = "lib"]
#![feature(unsized_fn_params)]
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
//@ [strong] compile-flags: -Z stack-protector=strong
//@ [basic] compile-flags: -Z stack-protector=basic
//@ [none] compile-flags: -Z stack-protector=none
//@ compile-flags: -C opt-level=2 -Z merge-functions=disabled -Cpanic=abort
//@ compile-flags: -Z allow-partial-mitigations=stack-protector -C opt-level=2 -Z merge-functions=disabled -Cpanic=abort

#![crate_type = "lib"]
#![feature(unsized_fn_params)]
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
//@ [strong] compile-flags: -Z stack-protector=strong
//@ [basic] compile-flags: -Z stack-protector=basic
//@ [none] compile-flags: -Z stack-protector=none
//@ compile-flags: -C opt-level=2 -Z merge-functions=disabled
//@ compile-flags: -C opt-level=2 -Z merge-functions=disabled -Z allow-partial-mitigations=stack-protector

// NOTE: the heuristics for stack smash protection inappropriately rely on types in LLVM IR,
// despite those types having no semantic meaning. This means that the `basic` and `strong`
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
//@ [safestack] compile-flags: -Z stack-protector=none -Z sanitizer=safestack
//@ [safestack_strong] compile-flags: -Z stack-protector=strong -Z sanitizer=safestack
//@ [safestack_all] compile-flags: -Z stack-protector=all -Z sanitizer=safestack
//@ compile-flags: -C opt-level=2 -Z merge-functions=disabled --target x86_64-unknown-linux-gnu
//@ compile-flags: -Z allow-partial-mitigations=stack-protector -C opt-level=2 -Z merge-functions=disabled --target x86_64-unknown-linux-gnu
//@ needs-llvm-components: x86

#![feature(unsized_fn_params)]
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -173,7 +173,7 @@
//@ [r84] needs-llvm-components: x86
//@ [r85] compile-flags: --target x86_64-unknown-redox
//@ [r85] needs-llvm-components: x86
//@ compile-flags: -Z stack-protector=all -Cpanic=abort
//@ compile-flags: -Z stack-protector=all -Z allow-partial-mitigations=stack-protector -Cpanic=abort
//@ compile-flags: -C opt-level=2

#![crate_type = "lib"]
Expand Down
6 changes: 3 additions & 3 deletions tests/codegen-llvm/stack-protector.rs
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
//@ revisions: all strong basic none
//@ ignore-nvptx64 stack protector not supported
//@ [all] compile-flags: -Z stack-protector=all
//@ [strong] compile-flags: -Z stack-protector=strong
//@ [basic] compile-flags: -Z stack-protector=basic
//@ [all] compile-flags: -Z stack-protector=all -Z allow-partial-mitigations=stack-protector
//@ [strong] compile-flags: -Z stack-protector=strong -Z allow-partial-mitigations=stack-protector
//@ [basic] compile-flags: -Z stack-protector=basic -Z allow-partial-mitigations=stack-protector

#![crate_type = "lib"]

Expand Down
2 changes: 1 addition & 1 deletion tests/ui/abi/stack-protector.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
//@ run-pass
//@ only-x86_64-unknown-linux-gnu
//@ revisions: ssp no-ssp
//@ [ssp] compile-flags: -Z stack-protector=all
//@ [ssp] compile-flags: -Z stack-protector=all -Z allow-partial-mitigations=stack-protector
//@ compile-flags: -C opt-level=2
//@ compile-flags: -g
//@ ignore-backends: gcc
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
// ignore-tidy-file-linelength
//@ revisions: control-flow-guard-future-allow-reset-by-mitigation
//@ check-fail
//@ ignore-nvptx64 stack protector is not supported
//@ ignore-wasm32-unknown-unknown stack protector is not supported
//@ edition:future

// msvc has an extra unwind dependency of std, normalize it in the error messages
//@ normalize-stderr: "\b(unwind|libc)\b" -> "unwind/libc"

// put the test for control-flow-guard in its own file since it does not have the future-compat warning,
// and you can't do negative revisions in compiletest

// check that `-C control-flow-guard` overrides the `-Z allow-partial-mitigations=control-flow-guard` (to the default, which is deny at edition=future)
//@ [control-flow-guard-future-allow-reset-by-mitigation] compile-flags: -Z unstable-options -Z allow-partial-mitigations=control-flow-guard -C control-flow-guard=on

fn main() {}
//~? ERROR that is not compiled with
//~? ERROR that is not compiled with
//~? ERROR that is not compiled with
//~? ERROR that is not compiled with
//~? ERROR that is not compiled with
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
// ignore-tidy-file-linelength
//@ revisions: stack-protector-future stack-protector-future-explicit-deny stack-protector-future-deny-reset-by-mitigation stack-protector-allow-then-deny stack-protector-but-allow-control-flow-guard control-flow-guard-future-allow-reset-by-mitigation stack-protector-future-allow-reset-by-mitigation stack-protector-future-deny-allow-reset-by-mitigation
//@ revisions: stack-protector-future stack-protector-future-explicit-deny stack-protector-future-deny-reset-by-mitigation stack-protector-allow-then-deny stack-protector-but-allow-control-flow-guard stack-protector-future-allow-reset-by-mitigation stack-protector-future-deny-allow-reset-by-mitigation
//@ check-fail
//@ compile-flags: -D future-incompatible
//@ ignore-nvptx64 stack protector is not supported
//@ ignore-wasm32-unknown-unknown stack protector is not supported
//@ edition:future
Expand All @@ -25,9 +26,6 @@
// check that allowing an unrelated mitigation (control-flow-guard) does not allow a different mitigation (stack-protector)
//@ [stack-protector-but-allow-control-flow-guard] compile-flags: -Z unstable-options -Z stack-protector=all -Z allow-partial-mitigations=control-flow-guard

// check that `-C control-flow-guard` overrides the `-Z allow-partial-mitigations=control-flow-guard` (to the default, which is deny at edition=future)
//@ [control-flow-guard-future-allow-reset-by-mitigation] compile-flags: -Z unstable-options -Z allow-partial-mitigations=control-flow-guard -C control-flow-guard=on

// check that `-Z stack-protector` overrides the `-Z allow-partial-mitigations=stack-protector` (to the default, which is deny at edition=future)
//@ [stack-protector-future-allow-reset-by-mitigation] compile-flags: -Z unstable-options -Z allow-partial-mitigations=stack-protector -Z stack-protector=all

Expand All @@ -40,3 +38,8 @@ fn main() {}
//~? ERROR that is not compiled with
//~? ERROR that is not compiled with
//~? ERROR that is not compiled with
//~? WARN this was previously accepted
//~? WARN this was previously accepted
//~? WARN this was previously accepted
//~? WARN this was previously accepted
//~? WARN this was previously accepted
Original file line number Diff line number Diff line change
Expand Up @@ -2,26 +2,38 @@ error: your program uses the crate `std`, that is not compiled with `stack-prote
|
= note: recompile `std` with `stack-protector=all` enabled, or use `-Z allow-partial-mitigations=stack-protector` to allow creating an artifact that has the mitigation partially enabled
= help: it is possible to disable `-Z allow-partial-mitigations=stack-protector` via `-Z deny-partial-mitigations=stack-protector`
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
= note: for more information, see issue #154613 <https://github.com/rust-lang/rust/issues/154613>
= note: `-D partial-stack-protector` implied by `-D future-incompatible`
= help: to override `-D future-incompatible` add `#[allow(partial_stack_protector)]`

error: your program uses the crate `core`, that is not compiled with `stack-protector=all` enabled
|
= note: recompile `core` with `stack-protector=all` enabled, or use `-Z allow-partial-mitigations=stack-protector` to allow creating an artifact that has the mitigation partially enabled
= help: it is possible to disable `-Z allow-partial-mitigations=stack-protector` via `-Z deny-partial-mitigations=stack-protector`
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
= note: for more information, see issue #154613 <https://github.com/rust-lang/rust/issues/154613>

error: your program uses the crate `alloc`, that is not compiled with `stack-protector=all` enabled
|
= note: recompile `alloc` with `stack-protector=all` enabled, or use `-Z allow-partial-mitigations=stack-protector` to allow creating an artifact that has the mitigation partially enabled
= help: it is possible to disable `-Z allow-partial-mitigations=stack-protector` via `-Z deny-partial-mitigations=stack-protector`
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
= note: for more information, see issue #154613 <https://github.com/rust-lang/rust/issues/154613>

error: your program uses the crate `compiler_builtins`, that is not compiled with `stack-protector=all` enabled
|
= note: recompile `compiler_builtins` with `stack-protector=all` enabled, or use `-Z allow-partial-mitigations=stack-protector` to allow creating an artifact that has the mitigation partially enabled
= help: it is possible to disable `-Z allow-partial-mitigations=stack-protector` via `-Z deny-partial-mitigations=stack-protector`
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
= note: for more information, see issue #154613 <https://github.com/rust-lang/rust/issues/154613>

error: your program uses the crate `unwind/libc`, that is not compiled with `stack-protector=all` enabled
|
= note: recompile `unwind/libc` with `stack-protector=all` enabled, or use `-Z allow-partial-mitigations=stack-protector` to allow creating an artifact that has the mitigation partially enabled
= help: it is possible to disable `-Z allow-partial-mitigations=stack-protector` via `-Z deny-partial-mitigations=stack-protector`
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
= note: for more information, see issue #154613 <https://github.com/rust-lang/rust/issues/154613>

error: aborting due to 5 previous errors

Loading
Loading