Skip to content

-Zharden-sls flag (target modifier) added to enable mitigation against straight line speculation (SLS) #136597

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
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
1 change: 1 addition & 0 deletions compiler/rustc_codegen_gcc/src/gcc_util.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ use smallvec::{SmallVec, smallvec};

fn gcc_features_by_flags(sess: &Session, features: &mut Vec<String>) {
target_features::retpoline_features_by_flags(sess, features);
target_features::sls_features_by_flags(sess, features);
// FIXME: LLVM also sets +reserve-x18 here under some conditions.
}

Expand Down
1 change: 1 addition & 0 deletions compiler/rustc_codegen_llvm/src/llvm_util.rs
Original file line number Diff line number Diff line change
Expand Up @@ -633,6 +633,7 @@ pub(crate) fn target_cpu(sess: &Session) -> &str {
/// The target features for compiler flags other than `-Ctarget-features`.
fn llvm_features_by_flags(sess: &Session, features: &mut Vec<String>) {
target_features::retpoline_features_by_flags(sess, features);
target_features::sls_features_by_flags(sess, features);

// -Zfixed-x18
if sess.opts.unstable_opts.fixed_x18 {
Expand Down
13 changes: 13 additions & 0 deletions compiler/rustc_codegen_ssa/src/target_features.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ use rustc_middle::middle::codegen_fn_attrs::TargetFeature;
use rustc_middle::query::Providers;
use rustc_middle::ty::TyCtxt;
use rustc_session::Session;
use rustc_session::config::HardenSls;
use rustc_session::lint::builtin::AARCH64_SOFTFLOAT_NEON;
use rustc_session::parse::feature_err;
use rustc_span::{Span, Symbol, sym};
Expand Down Expand Up @@ -400,6 +401,18 @@ pub fn retpoline_features_by_flags(sess: &Session, features: &mut Vec<String>) {
}
}

pub fn sls_features_by_flags(sess: &Session, features: &mut Vec<String>) {
match &sess.opts.unstable_opts.harden_sls {
HardenSls::None => (),
HardenSls::All => {
features.push("+harden-sls-ijmp".into());
features.push("+harden-sls-ret".into());
}
HardenSls::Return => features.push("+harden-sls-ret".into()),
HardenSls::IndirectJmp => features.push("+harden-sls-ijmp".into()),
}
}

pub(crate) fn provide(providers: &mut Providers) {
*providers = Providers {
rust_target_features: |tcx, cnum| {
Expand Down
21 changes: 16 additions & 5 deletions compiler/rustc_session/src/config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3172,11 +3172,11 @@ pub(crate) mod dep_tracking {
use super::{
AutoDiff, BranchProtection, CFGuard, CFProtection, CollapseMacroDebuginfo, CoverageOptions,
CrateType, DebugInfo, DebugInfoCompression, ErrorOutputType, FmtDebug, FunctionReturn,
InliningThreshold, InstrumentCoverage, InstrumentXRay, LinkerPluginLto, LocationDetail,
LtoCli, MirStripDebugInfo, NextSolverConfig, OomStrategy, OptLevel, OutFileName,
OutputType, OutputTypes, PatchableFunctionEntry, Polonius, RemapPathScopeComponents,
ResolveDocLinks, SourceFileHashAlgorithm, SplitDwarfKind, SwitchWithOptPath,
SymbolManglingVersion, WasiExecModel,
HardenSls, InliningThreshold, InstrumentCoverage, InstrumentXRay, LinkerPluginLto,
LocationDetail, LtoCli, MirStripDebugInfo, NextSolverConfig, OomStrategy, OptLevel,
OutFileName, OutputType, OutputTypes, PatchableFunctionEntry, Polonius,
RemapPathScopeComponents, ResolveDocLinks, SourceFileHashAlgorithm, SplitDwarfKind,
SwitchWithOptPath, SymbolManglingVersion, WasiExecModel,
};
use crate::lint;
use crate::utils::NativeLib;
Expand Down Expand Up @@ -3278,6 +3278,7 @@ pub(crate) mod dep_tracking {
Polonius,
InliningThreshold,
FunctionReturn,
HardenSls,
Align,
);

Expand Down Expand Up @@ -3532,6 +3533,16 @@ pub enum FunctionReturn {
ThunkExtern,
}

/// The different settings that the `-Zharden-sls` flag can have.
#[derive(Clone, Copy, PartialEq, Hash, Debug, Default)]
pub enum HardenSls {
#[default]
None,
All,
Return,
IndirectJmp,
}

/// Whether extra span comments are included when dumping MIR, via the `-Z mir-include-spans` flag.
/// By default, only enabled in the NLL MIR dumps, and disabled in all other passes.
#[derive(Clone, Copy, Default, PartialEq, Debug)]
Expand Down
15 changes: 15 additions & 0 deletions compiler/rustc_session/src/options.rs
Original file line number Diff line number Diff line change
Expand Up @@ -808,6 +808,7 @@ mod desc {
"either a boolean (`yes`, `no`, `on`, `off`, etc), or a non-negative number";
pub(crate) const parse_llvm_module_flag: &str = "<key>:<type>:<value>:<behavior>. Type must currently be `u32`. Behavior should be one of (`error`, `warning`, `require`, `override`, `append`, `appendunique`, `max`, `min`)";
pub(crate) const parse_function_return: &str = "`keep` or `thunk-extern`";
pub(crate) const parse_harden_sls: &str = "`none`, `all`, `return` or `indirect-jmp`";
pub(crate) const parse_wasm_c_abi: &str = "`spec`";
pub(crate) const parse_mir_include_spans: &str =
"either a boolean (`yes`, `no`, `on`, `off`, etc), or `nll` (default: `nll`)";
Expand Down Expand Up @@ -1917,6 +1918,17 @@ pub mod parse {
true
}

pub(crate) fn parse_harden_sls(slot: &mut HardenSls, v: Option<&str>) -> bool {
match v {
Some("none") => *slot = HardenSls::None,
Some("all") => *slot = HardenSls::All,
Some("return") => *slot = HardenSls::Return,
Some("indirect-jmp") => *slot = HardenSls::IndirectJmp,
_ => return false,
}
true
}

pub(crate) fn parse_wasm_c_abi(_slot: &mut (), v: Option<&str>) -> bool {
v == Some("spec")
}
Expand Down Expand Up @@ -2254,6 +2266,9 @@ options! {
graphviz_font: String = ("Courier, monospace".to_string(), parse_string, [UNTRACKED],
"use the given `fontname` in graphviz output; can be overridden by setting \
environment variable `RUSTC_GRAPHVIZ_FONT` (default: `Courier, monospace`)"),
harden_sls: HardenSls = (HardenSls::None, parse_harden_sls, [TRACKED TARGET_MODIFIER],
"flag to mitigate against straight line speculation (SLS) [none|all|return|indirect-jmp] \
(default: none)"),
has_thread_local: Option<bool> = (None, parse_opt_bool, [TRACKED],
"explicitly enable the `cfg(target_thread_local)` directive"),
hint_mostly_unused: bool = (false, parse_bool, [TRACKED],
Expand Down
10 changes: 10 additions & 0 deletions compiler/rustc_target/src/target_features.rs
Original file line number Diff line number Diff line change
Expand Up @@ -433,6 +433,16 @@ static X86_FEATURES: &[(&str, Stability, ImpliedFeatures)] = &[
("fma", Stable, &["avx"]),
("fxsr", Stable, &[]),
("gfni", Stable, &["sse2"]),
(
"harden-sls-ijmp",
Stability::Forbidden { reason: "use `harden-sls` compiler flag instead" },
&[],
),
(
"harden-sls-ret",
Stability::Forbidden { reason: "use `harden-sls` compiler flag instead" },
&[],
),
("kl", Stable, &["sse2"]),
("lahfsahf", Unstable(sym::lahfsahf_target_feature), &[]),
("lzcnt", Stable, &[]),
Expand Down
35 changes: 35 additions & 0 deletions tests/codegen/harden-sls.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
// ignore-tidy-linelength
// Test that the `harden-sls-ijmp`, `harden-sls-ret` target features is (not) emitted when
// the `harden-sls=[none|all|return|indirect-jmp]` flag is (not) set.

//@ add-core-stubs
//@ revisions: none all return indirect_jmp
//@ needs-llvm-components: x86
//@ compile-flags: --target x86_64-unknown-linux-gnu
//@ [none] compile-flags: -Zharden-sls=none
//@ [all] compile-flags: -Zharden-sls=all
//@ [return] compile-flags: -Zharden-sls=return
//@ [indirect_jmp] compile-flags: -Zharden-sls=indirect-jmp

#![crate_type = "lib"]
#![feature(no_core)]
#![no_core]

extern crate minicore;
use minicore::*;

#[no_mangle]
pub fn foo() {
// CHECK: @foo() unnamed_addr #0

// none-NOT: attributes #0 = { {{.*}}"target-features"="{{[^"]*}}+harden-sls-ijmp{{.*}} }
// none-NOT: attributes #0 = { {{.*}}"target-features"="{{[^"]*}}+harden-sls-ret{{.*}} }

// all: attributes #0 = { {{.*}}"target-features"="{{[^"]*}}+harden-sls-ijmp,+harden-sls-ret{{.*}} }

// return-NOT: attributes #0 = { {{.*}}"target-features"="{{[^"]*}}+harden-sls-ijmp{{.*}} }
// return: attributes #0 = { {{.*}}"target-features"="{{[^"]*}}+harden-sls-ret{{.*}} }

// indirect_jmp-NOT: attributes #0 = { {{.*}}"target-features"="{{[^"]*}}+harden-sls-ret{{.*}} }
// indirect_jmp: attributes #0 = { {{.*}}"target-features"="{{[^"]*}}+harden-sls-ijmp{{.*}} }
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
warning: target feature `harden-sls-ijmp` cannot be enabled with `-Ctarget-feature`: use `harden-sls` compiler flag instead
|
= note: 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 #116344 <https://github.com/rust-lang/rust/issues/116344>

warning: target feature `harden-sls-ret` cannot be enabled with `-Ctarget-feature`: use `harden-sls` compiler flag instead
|
= note: 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 #116344 <https://github.com/rust-lang/rust/issues/116344>

warning: 2 warnings emitted

15 changes: 15 additions & 0 deletions tests/ui/target-feature/harden-sls-target-feature-flag.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
//@ add-core-stubs
//@ revisions: by_flag by_feature
//@ compile-flags: --target=x86_64-unknown-linux-gnu --crate-type=lib
//@ needs-llvm-components: x86
//@ [by_flag]compile-flags: -Zharden-sls=all
//@ [by_feature]compile-flags: -Ctarget-feature=+harden-sls-ijmp,+harden-sls-ret
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

These should not be set by -Ctarget-feature.

//@ [by_flag]build-pass
// For now this is just a warning.
//@ [by_feature]build-pass
#![feature(no_core, lang_items)]
#![no_std]
#![no_core]

//[by_feature]~? WARN target feature `harden-sls-ijmp` cannot be enabled with `-Ctarget-feature`: use `harden-sls` compiler flag instead
//[by_feature]~? WARN target feature `harden-sls-ret` cannot be enabled with `-Ctarget-feature`: use `harden-sls` compiler flag instead
Loading