From e83c688c001419caf902a1883507e32a0d6eda8a Mon Sep 17 00:00:00 2001 From: Ariel Ben-Yehuda Date: Mon, 8 Sep 2025 16:47:37 +0000 Subject: [PATCH 1/9] Stabilize `-Zstack-protector` as `-Cstack-protector` I propose stabilizing `-Cstack-protector` as `-Zstack-protector`. This PR adds a new `-Cstack-protector` flag, leaving the unstable `-Z` flag as is to ease the transition period. The `-Z` flag will be removed in the future. No RFC/MCP, this flag was added in 84197 and was not deemed large enough to require additional process. The tracking issue for this feature is 114903. The `-Cstack-protector=strong` mode uses the same underlying heuristics as Clang's `-fstack-protector-strong`. These heuristics weren't designed for Rust, and may be over-conservative in some cases - for example, if Rust stores a field's data in an alloca using an LLVM array type, LLVM regard the alloca as meaning that the function has a C array, and enable stack overflow canaries even if the function accesses the alloca in a safe way. Some people thought we should wait on stabilization until there are better heuristics, but I didn't hear about any concrete case where this unduly harms performance, and I think that when a need comes, we can improve the heuristics in LLVM after stabilization. The heuristics do seem to not be under-conservative, so this should not be a security risk. The `-Cstack-protector=basic` mode (`-fstack-protector`) uses heuristics that are specifically designed to catch old-C-style string manipulation. This is not a good fit to Rust, which does not perform much unsafe C-style string manipulation. As far as I can tell, nobody has been asking for it, and few people are using it even in today's C - modern distros (e.g. [Debian]) tend to use `-fstack-protector-strong`. Therefore, `-Cstack-protector=basic` has been **removed**. If anyone is interested in it, they are welcome to add it back as an unstable option. [Debian]: https://wiki.debian.org/Hardening#DEB_BUILD_HARDENING_STACKPROTECTOR_.28gcc.2Fg.2B-.2B-_-fstack-protector-strong.29 Most implementation was done in . The command-line attribute enables the relevant LLVM attribute on all functions in . Each target can indicate that it does not support stack canaries - currently, the GPU platforms `nvptx64-nvidia-cuda` and `amdgcn-amd-amdhsa`. On these platforms, use of `-Cstack-protector` causes an error. The feature has tests that make sure that the LLVM heuristic gives reasonable results for several functions, by checking for `__security_check_cookie` (on Windows) or `__stack_chk_fail` (on Linux). See No call-for-testing has been conducted, but the feature seems to be in use. No reported bugs seem to exist. - bbjornse was the original implementor at 84197 - mrcnski documented it at 111722 - wesleywiser added tests for Windows at 116037 - davidtwco worked on the feature at 121742 - nikic provided support from the LLVM side (on Zulip on and elsewhere), thanks nikic! No FIXMEs related to this feature. This feature cannot cause undefined behavior. No changes to reference/spec, docs added to the codegen docs as part of the stabilization PR. No. None. No support needed for rustdoc, clippy, rust-analyzer, rustfmt or rustup. Cargo could expose this as an option in build profiles but I would expect the decision as to what version should be used would be made for the entire crate graph at build time rather than by individual package authors. `-C stack-protector` is propagated to C compilers using cc-rs via rust-lang/cc-rs issue 1550 --- bootstrap.example.toml | 2 +- compiler/rustc_codegen_llvm/src/lib.rs | 29 ++++++++++----- compiler/rustc_interface/src/tests.rs | 2 +- compiler/rustc_session/messages.ftl | 2 +- compiler/rustc_session/src/options.rs | 12 +++++-- compiler/rustc_session/src/session.rs | 17 ++++----- src/bootstrap/src/core/builder/cargo.rs | 2 +- src/doc/rustc/src/codegen-options/index.md | 28 +++++++++++++++ src/doc/rustc/src/exploit-mitigations.md | 2 +- ...otector-heuristics-effect-windows-32bit.rs | 8 ++--- ...otector-heuristics-effect-windows-64bit.rs | 8 ++--- .../stack-protector-heuristics-effect.rs | 8 ++--- .../stack-protector-target-support.rs | 12 +++---- tests/codegen-llvm/stack-protector.rs | 36 ++++++++++++++++--- tests/ui/README.md | 2 +- tests/ui/abi/stack-protector.rs | 2 +- ...l-stack-protector-unsupported.all-z.stderr | 4 +++ ...ail-stack-protector-unsupported.all.stderr | 4 +++ .../fail-stack-protector-unsupported.rs | 30 ++++++++++++++++ ...-stack-protector-unsupported.strong.stderr | 4 +++ ...arn-stack-protector-unsupported.all.stderr | 4 --- ...n-stack-protector-unsupported.basic.stderr | 4 --- ...-stack-protector-unsupported.strong.stderr | 4 --- 23 files changed, 164 insertions(+), 62 deletions(-) create mode 100644 tests/ui/stack-protector/fail-stack-protector-unsupported.all-z.stderr create mode 100644 tests/ui/stack-protector/fail-stack-protector-unsupported.all.stderr create mode 100644 tests/ui/stack-protector/fail-stack-protector-unsupported.rs create mode 100644 tests/ui/stack-protector/fail-stack-protector-unsupported.strong.stderr delete mode 100644 tests/ui/stack-protector/warn-stack-protector-unsupported.all.stderr delete mode 100644 tests/ui/stack-protector/warn-stack-protector-unsupported.basic.stderr delete mode 100644 tests/ui/stack-protector/warn-stack-protector-unsupported.strong.stderr diff --git a/bootstrap.example.toml b/bootstrap.example.toml index 4e850810a30a9..1be2bef14eb85 100644 --- a/bootstrap.example.toml +++ b/bootstrap.example.toml @@ -727,7 +727,7 @@ #rust.frame-pointers = false # Indicates whether stack protectors should be used -# via the unstable option `-Zstack-protector`. +# via `-Cstack-protector`. # # Valid options are : `none`(default),`basic`,`strong`, or `all`. # `strong` and `basic` options may be buggy and are not recommended, see rust-lang/rust#114903. diff --git a/compiler/rustc_codegen_llvm/src/lib.rs b/compiler/rustc_codegen_llvm/src/lib.rs index 8c0c0afcc1dd7..a351100e1fea3 100644 --- a/compiler/rustc_codegen_llvm/src/lib.rs +++ b/compiler/rustc_codegen_llvm/src/lib.rs @@ -283,19 +283,32 @@ impl CodegenBackend for LlvmCodegenBackend { Generate stack canaries in all functions. strong - Generate stack canaries in a function if it either: - - has a local variable of `[T; N]` type, regardless of `T` and `N` - - takes the address of a local variable. + Generate stack canaries for all functions, unless the compiler + can prove these functions can't be the source of a stack + buffer overflow (even in the presence of undefined behavior). - (Note that a local variable being borrowed is not equivalent to its - address being taken: e.g. some borrows may be removed by optimization, - while by-value argument passing may be implemented with reference to a - local stack variable in the ABI.) + This provides the same security guarantees as Clang's + `-fstack-protector=strong`. + + The exact rules are unstable and subject to change, but + currently, it generates stack protectors for functions that, + *post-optimization*, contain either arrays (of any size + or type) or address-taken locals. basic - Generate stack canaries in functions with local variables of `[T; N]` + Generate stack canaries in functions that are heuristically + suspected to contain buffer overflows. + + The heuristic is subject to change, but currently it + includes functions with local variables of `[T; N]` type, where `T` is byte-sized and `N` >= 8. + This heuristic originated from C, where it detects + functions that allocate a `char buf[N];` buffer on the + stack, and are therefore likely to have a stack buffer overflow + in the case of a length-calculation error. It is *not* a good + heuristic for Rust code. + none Do not generate stack canaries. "# diff --git a/compiler/rustc_interface/src/tests.rs b/compiler/rustc_interface/src/tests.rs index 89b8a5fddb89e..136ef871942af 100644 --- a/compiler/rustc_interface/src/tests.rs +++ b/compiler/rustc_interface/src/tests.rs @@ -641,6 +641,7 @@ fn test_codegen_options_tracking_hash() { tracked!(relro_level, Some(RelroLevel::Full)); tracked!(soft_float, true); tracked!(split_debuginfo, Some(SplitDebuginfo::Packed)); + tracked!(stack_protector, StackProtector::All); tracked!(symbol_mangling_version, Some(SymbolManglingVersion::V0)); tracked!(target_cpu, Some(String::from("abc"))); tracked!(target_feature, String::from("all the features, all of them")); @@ -871,7 +872,6 @@ fn test_unstable_options_tracking_hash() { tracked!(small_data_threshold, Some(16)); tracked!(split_lto_unit, Some(true)); tracked!(src_hash_algorithm, Some(SourceFileHashAlgorithm::Sha1)); - tracked!(stack_protector, StackProtector::All); tracked!(teach, true); tracked!(thinlto, Some(true)); tracked!(tiny_const_eval_limit, true); diff --git a/compiler/rustc_session/messages.ftl b/compiler/rustc_session/messages.ftl index a4166951e350a..1426d885551be 100644 --- a/compiler/rustc_session/messages.ftl +++ b/compiler/rustc_session/messages.ftl @@ -129,7 +129,7 @@ session_target_requires_unwind_tables = target requires unwind tables, they cann session_target_small_data_threshold_not_supported = `-Z small-data-threshold` is not supported for target {$target_triple} and will be ignored -session_target_stack_protector_not_supported = `-Z stack-protector={$stack_protector}` is not supported for target {$target_triple} and will be ignored +session_target_stack_protector_not_supported = `-C stack-protector={$stack_protector}` is not supported for target {$target_triple} session_unexpected_builtin_cfg = unexpected `--cfg {$cfg}` flag .controlled_by = config `{$cfg_name}` is only supposed to be controlled by `{$controlled_by}` diff --git a/compiler/rustc_session/src/options.rs b/compiler/rustc_session/src/options.rs index 92dd4a23125cc..1034126bcffbd 100644 --- a/compiler/rustc_session/src/options.rs +++ b/compiler/rustc_session/src/options.rs @@ -1889,9 +1889,12 @@ pub mod parse { true } - pub(crate) fn parse_stack_protector(slot: &mut StackProtector, v: Option<&str>) -> bool { + pub(crate) fn parse_stack_protector( + slot: &mut Option, + v: Option<&str>, + ) -> bool { match v.and_then(|s| StackProtector::from_str(s).ok()) { - Some(ssp) => *slot = ssp, + Some(ssp) => *slot = Some(ssp), _ => return false, } true @@ -2183,6 +2186,9 @@ options! { #[rustc_lint_opt_deny_field_access("use `Session::split_debuginfo` instead of this field")] split_debuginfo: Option = (None, parse_split_debuginfo, [TRACKED], "how to handle split-debuginfo, a platform-specific option"), + #[rustc_lint_opt_deny_field_access("use `Session::stack_protector` instead of this field")] + stack_protector: Option = (None, parse_stack_protector, [TRACKED], + "control stack smash protection strategy (`rustc --print stack-protector-strategies` for details)"), strip: Strip = (Strip::None, parse_strip, [UNTRACKED], "tell the linker which information to strip (`none` (default), `debuginfo` or `symbols`)"), symbol_mangling_version: Option = (None, @@ -2659,7 +2665,7 @@ written to standard error output)"), src_hash_algorithm: Option = (None, parse_src_file_hash, [TRACKED], "hash algorithm of source files in debug info (`md5`, `sha1`, or `sha256`)"), #[rustc_lint_opt_deny_field_access("use `Session::stack_protector` instead of this field")] - stack_protector: StackProtector = (StackProtector::None, parse_stack_protector, [TRACKED], + stack_protector: Option = (None, parse_stack_protector, [TRACKED], "control stack smash protection strategy (`rustc --print stack-protector-strategies` for details)"), staticlib_allow_rdylib_deps: bool = (false, parse_bool, [TRACKED], "allow staticlibs to have rust dylib dependencies"), diff --git a/compiler/rustc_session/src/session.rs b/compiler/rustc_session/src/session.rs index acc65fc11a2a2..72c7877727685 100644 --- a/compiler/rustc_session/src/session.rs +++ b/compiler/rustc_session/src/session.rs @@ -713,11 +713,12 @@ impl Session { } pub fn stack_protector(&self) -> StackProtector { - if self.target.options.supports_stack_protector { - self.opts.unstable_opts.stack_protector - } else { - StackProtector::None - } + // -C stack-protector overwrites -Z stack-protector, default to StackProtector::None + self.opts + .cg + .stack_protector + .or(self.opts.unstable_opts.stack_protector) + .unwrap_or(StackProtector::None) } pub fn must_emit_unwind_tables(&self) -> bool { @@ -1268,10 +1269,10 @@ fn validate_commandline_args_with_session_available(sess: &Session) { } } - if sess.opts.unstable_opts.stack_protector != StackProtector::None { + if sess.stack_protector() != StackProtector::None { if !sess.target.options.supports_stack_protector { - sess.dcx().emit_warn(errors::StackProtectorNotSupportedForTarget { - stack_protector: sess.opts.unstable_opts.stack_protector, + sess.dcx().emit_err(errors::StackProtectorNotSupportedForTarget { + stack_protector: sess.stack_protector(), target_triple: &sess.opts.target_triple, }); } diff --git a/src/bootstrap/src/core/builder/cargo.rs b/src/bootstrap/src/core/builder/cargo.rs index 2ca52c72e5ec7..f0daddb0d6e6e 100644 --- a/src/bootstrap/src/core/builder/cargo.rs +++ b/src/bootstrap/src/core/builder/cargo.rs @@ -945,7 +945,7 @@ impl Builder<'_> { cargo.env(profile_var("STRIP"), self.config.rust_strip.to_string()); if let Some(stack_protector) = &self.config.rust_stack_protector { - rustflags.arg(&format!("-Zstack-protector={stack_protector}")); + rustflags.arg(&format!("-Cstack-protector={stack_protector}")); } let debuginfo_level = match mode { diff --git a/src/doc/rustc/src/codegen-options/index.md b/src/doc/rustc/src/codegen-options/index.md index f0f991ed0c909..57bd3f3e0b316 100644 --- a/src/doc/rustc/src/codegen-options/index.md +++ b/src/doc/rustc/src/codegen-options/index.md @@ -695,6 +695,34 @@ Note that all three options are supported on Linux and Apple platforms, Attempting to use an unsupported option requires using the nightly channel with the `-Z unstable-options` flag. +## stack-protector + +The option `-C stack-protector` (currently also supported in the +old style `-Z stack-protector`) controls the generation of +stack-protector canaries. + +This flag controls stack smashing protection strategy. + +Supported values for this option are: +- `none` (default): Disable stack canary generation +- `basic`: Generate stack canaries in functions that are suspected + to have a high chance of containing stack buffer overflows (deprecated). +- `strong`: Generate stack canaries in all functions, unless the compiler + can prove these functions can't be the source of a stack + buffer overflow (even in the presence of undefined behavior). + + This provides the same security guarantees as Clang's + `-fstack-protector=strong`. + + The exact rules are unstable and subject to change, but + currently, it generates stack protectors for functions that, + *post-optimization*, contain either arrays (of any size + or type) or address-taken locals. +- `all`: Generate stack canaries in all functions + +Stack protectors are not supported on many GPU targets, use of stack +protectors on these targets is an error. + ## strip The option `-C strip=val` controls stripping of debuginfo and similar auxiliary diff --git a/src/doc/rustc/src/exploit-mitigations.md b/src/doc/rustc/src/exploit-mitigations.md index 41e5c93a1b7dc..2523cdeb3b099 100644 --- a/src/doc/rustc/src/exploit-mitigations.md +++ b/src/doc/rustc/src/exploit-mitigations.md @@ -62,7 +62,7 @@ equivalent. | Stack clashing protection | Yes | Yes | 1.20.0 (2017-08-31) | | Read-only relocations and immediate binding | Yes | Yes | 1.21.0 (2017-10-12) | | Heap corruption protection | Yes | Yes | 1.32.0 (2019-01-17) (via operating system default or specified allocator) | -| Stack smashing protection | Yes | No, `-Z stack-protector` | Nightly | +| Stack smashing protection | Yes | No, `-C stack-protector` | ??? | | Forward-edge control flow protection | Yes | No, `-Z sanitizer=cfi` | Nightly | | Backward-edge control flow protection (e.g., shadow and safe stack) | Yes | No, `-Z sanitizer=shadow-call-stack,safestack` | Nightly | diff --git a/tests/assembly-llvm/stack-protector/stack-protector-heuristics-effect-windows-32bit.rs b/tests/assembly-llvm/stack-protector/stack-protector-heuristics-effect-windows-32bit.rs index 3287e018b4044..0d7a5453cc19d 100644 --- a/tests/assembly-llvm/stack-protector/stack-protector-heuristics-effect-windows-32bit.rs +++ b/tests/assembly-llvm/stack-protector/stack-protector-heuristics-effect-windows-32bit.rs @@ -3,10 +3,10 @@ //@ only-windows //@ only-msvc //@ ignore-64bit 64-bit table based SEH has slightly different behaviors than classic SEH -//@ [all] compile-flags: -Z stack-protector=all -//@ [strong] compile-flags: -Z stack-protector=strong -//@ [basic] compile-flags: -Z stack-protector=basic -//@ [none] compile-flags: -Z stack-protector=none +//@ [all] compile-flags: -C stack-protector=all +//@ [strong] compile-flags: -C stack-protector=strong +//@ [basic] compile-flags: -C stack-protector=basic +//@ [none] compile-flags: -C stack-protector=none //@ compile-flags: -C opt-level=2 -Z merge-functions=disabled #![crate_type = "lib"] diff --git a/tests/assembly-llvm/stack-protector/stack-protector-heuristics-effect-windows-64bit.rs b/tests/assembly-llvm/stack-protector/stack-protector-heuristics-effect-windows-64bit.rs index 9a3dabc74dded..db592fc3ec770 100644 --- a/tests/assembly-llvm/stack-protector/stack-protector-heuristics-effect-windows-64bit.rs +++ b/tests/assembly-llvm/stack-protector/stack-protector-heuristics-effect-windows-64bit.rs @@ -3,10 +3,10 @@ //@ only-windows //@ only-msvc //@ ignore-32bit 64-bit table based SEH has slightly different behaviors than classic SEH -//@ [all] compile-flags: -Z stack-protector=all -//@ [strong] compile-flags: -Z stack-protector=strong -//@ [basic] compile-flags: -Z stack-protector=basic -//@ [none] compile-flags: -Z stack-protector=none +//@ [all] compile-flags: -C stack-protector=all +//@ [strong] compile-flags: -C stack-protector=strong +//@ [basic] compile-flags: -C stack-protector=basic +//@ [none] compile-flags: -C stack-protector=none //@ compile-flags: -C opt-level=2 -Z merge-functions=disabled #![crate_type = "lib"] diff --git a/tests/assembly-llvm/stack-protector/stack-protector-heuristics-effect.rs b/tests/assembly-llvm/stack-protector/stack-protector-heuristics-effect.rs index 3728ff3adf105..31a31a807a613 100644 --- a/tests/assembly-llvm/stack-protector/stack-protector-heuristics-effect.rs +++ b/tests/assembly-llvm/stack-protector/stack-protector-heuristics-effect.rs @@ -4,10 +4,10 @@ //@ ignore-msvc stack check code uses different function names //@ ignore-nvptx64 stack protector is not supported //@ ignore-wasm32-unknown-unknown -//@ [all] compile-flags: -Z stack-protector=all -//@ [strong] compile-flags: -Z stack-protector=strong -//@ [basic] compile-flags: -Z stack-protector=basic -//@ [none] compile-flags: -Z stack-protector=none +//@ [all] compile-flags: -C stack-protector=all +//@ [strong] compile-flags: -C stack-protector=strong +//@ [basic] compile-flags: -C stack-protector=basic +//@ [none] compile-flags: -C stack-protector=none //@ compile-flags: -C opt-level=2 -Z merge-functions=disabled // NOTE: the heuristics for stack smash protection inappropriately rely on types in LLVM IR, diff --git a/tests/assembly-llvm/stack-protector/stack-protector-target-support.rs b/tests/assembly-llvm/stack-protector/stack-protector-target-support.rs index 0218fe0a52f8a..b10faf233e239 100644 --- a/tests/assembly-llvm/stack-protector/stack-protector-target-support.rs +++ b/tests/assembly-llvm/stack-protector/stack-protector-target-support.rs @@ -4,7 +4,7 @@ //@ add-minicore //@ revisions: r1 r2 r3 r4 r5 r6 r7 r8 r9 r10 r11 r12 r13 r14 r15 r16 r17 r18 r19 r20 r21 r22 r23 //@ revisions: r24 r25 r26 r27 r28 r29 r30 r31 r32 r33 r36 r37 r38 r39 r40 r41 r42 r43 r44 -//@ revisions: r45 r46 r47 r48 r49 r50 r51 r52 r53 r54 r55 r56 r57 r58 r59 r60 r61 r62 r63 r64 r65 +//@ revisions: r45 r46 r47 r48 r50 r51 r52 r53 r54 r55 r56 r57 r58 r59 r60 r61 r62 r63 r64 r65 //@ revisions: r66 r67 r68 r69 r70 r71 r72 r73 r74 r75 r76 r77 r78 r79 r80 r81 r82 r83 r84 r85 //@ assembly-output: emit-asm //@ [r1] compile-flags: --target aarch64-unknown-linux-gnu @@ -99,8 +99,8 @@ //@ [r47] needs-llvm-components: mips //@ [r48] compile-flags: --target mipsel-unknown-linux-musl //@ [r48] needs-llvm-components: mips -//@ [r49] compile-flags: --target nvptx64-nvidia-cuda -//@ [r49] needs-llvm-components: nvptx +//-@ [r49] compile-flags: --target nvptx64-nvidia-cuda [stack protector not supported on CUDA +//- see the test fail-stack-protector-unsupported] //@ [r50] compile-flags: --target powerpc-unknown-linux-gnu //@ [r50] needs-llvm-components: powerpc //@ [r51] compile-flags: --target powerpc64-unknown-linux-gnu @@ -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 +//@ compile-flags: -C stack-protector=all //@ compile-flags: -C opt-level=2 #![crate_type = "lib"] @@ -193,10 +193,6 @@ pub fn foo() { // r7: callq __security_check_cookie // r13: bl __security_check_cookie - // cuda doesn't support stack-smash protection - // r49-NOT: __security_check_cookie - // r49-NOT: __stack_chk_fail - // Other targets do stack checking within the function, and call a failure function on error // r1: __stack_chk_fail // r2: __stack_chk_fail diff --git a/tests/codegen-llvm/stack-protector.rs b/tests/codegen-llvm/stack-protector.rs index 8ab25b470cda1..686db3f1f4412 100644 --- a/tests/codegen-llvm/stack-protector.rs +++ b/tests/codegen-llvm/stack-protector.rs @@ -1,8 +1,12 @@ -//@ revisions: all strong basic none +//@ revisions: all all-z strong strong-z basic basic-z none strong-c-overrides-z //@ 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: -C stack-protector=all +//@ [all-z] compile-flags: -Z stack-protector=all +//@ [strong] compile-flags: -C stack-protector=strong +//@ [strong-z] compile-flags: -Z stack-protector=strong +//@ [basic] compile-flags: -C stack-protector=basic +//@ [basic-z] compile-flags: -Z stack-protector=basic +//@ [strong-c-overrides-z] compile-flags: -C stack-protector=strong -Z stack-protector=all #![crate_type = "lib"] @@ -16,18 +20,42 @@ pub fn foo() { // all-NOT: attributes #0 = { {{.*}}sspstrong {{.*}} } // all-NOT: attributes #0 = { {{.*}}ssp {{.*}} } + // all-z-NOT: attributes #0 = { {{.*}}sspstrong {{.*}} } + // all-z-NOT: attributes #0 = { {{.*}}ssp {{.*}} } + // all-z: attributes #0 = { {{.*}}sspreq {{.*}} } + // all-z-NOT: attributes #0 = { {{.*}}sspstrong {{.*}} } + // all-z-NOT: attributes #0 = { {{.*}}ssp {{.*}} } + // strong-NOT: attributes #0 = { {{.*}}sspreq {{.*}} } // strong-NOT: attributes #0 = { {{.*}}ssp {{.*}} } // strong: attributes #0 = { {{.*}}sspstrong {{.*}} } // strong-NOT: attributes #0 = { {{.*}}sspreq {{.*}} } // strong-NOT: attributes #0 = { {{.*}}ssp {{.*}} } + // strong-z-NOT: attributes #0 = { {{.*}}sspreq {{.*}} } + // strong-z-NOT: attributes #0 = { {{.*}}ssp {{.*}} } + // strong-z: attributes #0 = { {{.*}}sspstrong {{.*}} } + // strong-z-NOT: attributes #0 = { {{.*}}sspreq {{.*}} } + // strong-z-NOT: attributes #0 = { {{.*}}ssp {{.*}} } + + // strong-c-overrides-z-NOT: attributes #0 = { {{.*}}sspreq {{.*}} } + // strong-c-overrides-z-NOT: attributes #0 = { {{.*}}ssp {{.*}} } + // strong-c-overrides-z: attributes #0 = { {{.*}}sspstrong {{.*}} } + // strong-c-overrides-z-NOT: attributes #0 = { {{.*}}sspreq {{.*}} } + // strong-c-overrides-z-NOT: attributes #0 = { {{.*}}ssp {{.*}} } + // basic-NOT: attributes #0 = { {{.*}}sspreq {{.*}} } // basic-NOT: attributes #0 = { {{.*}}sspstrong {{.*}} } // basic: attributes #0 = { {{.*}}ssp {{.*}} } // basic-NOT: attributes #0 = { {{.*}}sspreq {{.*}} } // basic-NOT: attributes #0 = { {{.*}}sspstrong {{.*}} } + // basic-z-NOT: attributes #0 = { {{.*}}sspreq {{.*}} } + // basic-z-NOT: attributes #0 = { {{.*}}sspstrong {{.*}} } + // basic-z: attributes #0 = { {{.*}}ssp {{.*}} } + // basic-z-NOT: attributes #0 = { {{.*}}sspreq {{.*}} } + // basic-z-NOT: attributes #0 = { {{.*}}sspstrong {{.*}} } + // none-NOT: attributes #0 = { {{.*}}sspreq {{.*}} } // none-NOT: attributes #0 = { {{.*}}sspstrong {{.*}} } // none-NOT: attributes #0 = { {{.*}}ssp {{.*}} } diff --git a/tests/ui/README.md b/tests/ui/README.md index 25e870fd8f188..babc19e4f8f2e 100644 --- a/tests/ui/README.md +++ b/tests/ui/README.md @@ -1235,7 +1235,7 @@ Stability attributes used internally by the standard library: `#[stable()]` and Some tests for pretty printing of rustc_public's IR. -## `tests/ui/stack-protector/`: `-Z stack-protector` command line flag +## `tests/ui/stack-protector/`: `-C stack-protector` command line flag See [Tracking Issue for stabilizing stack smashing protection (i.e., `-Z stack-protector`) #114903](https://github.com/rust-lang/rust/issues/114903). diff --git a/tests/ui/abi/stack-protector.rs b/tests/ui/abi/stack-protector.rs index dd0d0d43182ea..3c52d9ff1ae4d 100644 --- a/tests/ui/abi/stack-protector.rs +++ b/tests/ui/abi/stack-protector.rs @@ -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: -C stack-protector=all //@ compile-flags: -C opt-level=2 //@ compile-flags: -g //@ ignore-backends: gcc diff --git a/tests/ui/stack-protector/fail-stack-protector-unsupported.all-z.stderr b/tests/ui/stack-protector/fail-stack-protector-unsupported.all-z.stderr new file mode 100644 index 0000000000000..9f2876de057fd --- /dev/null +++ b/tests/ui/stack-protector/fail-stack-protector-unsupported.all-z.stderr @@ -0,0 +1,4 @@ +error: `-C stack-protector=all` is not supported for target nvptx64-nvidia-cuda + +error: aborting due to 1 previous error + diff --git a/tests/ui/stack-protector/fail-stack-protector-unsupported.all.stderr b/tests/ui/stack-protector/fail-stack-protector-unsupported.all.stderr new file mode 100644 index 0000000000000..9f2876de057fd --- /dev/null +++ b/tests/ui/stack-protector/fail-stack-protector-unsupported.all.stderr @@ -0,0 +1,4 @@ +error: `-C stack-protector=all` is not supported for target nvptx64-nvidia-cuda + +error: aborting due to 1 previous error + diff --git a/tests/ui/stack-protector/fail-stack-protector-unsupported.rs b/tests/ui/stack-protector/fail-stack-protector-unsupported.rs new file mode 100644 index 0000000000000..c9eb3560eda42 --- /dev/null +++ b/tests/ui/stack-protector/fail-stack-protector-unsupported.rs @@ -0,0 +1,30 @@ +//@ check-fail +//@ revisions: all strong all-z +//@ compile-flags: --target nvptx64-nvidia-cuda +//@ needs-llvm-components: nvptx +//@ [all] compile-flags: -C stack-protector=all +//@ [strong] compile-flags: -C stack-protector=strong +//@ [all-z] compile-flags: -Z stack-protector=all + +#![crate_type = "lib"] +#![feature(no_core, lang_items)] +#![no_std] +#![no_core] + +#[lang = "pointee_sized"] +pub trait PointeeSized {} + +#[lang = "meta_sized"] +pub trait MetaSized: PointeeSized {} + +#[lang = "sized"] +trait Sized: MetaSized {} + +#[lang = "copy"] +trait Copy {} + +pub fn main(){} + +//[all]~? ERROR `-C stack-protector=all` is not supported for target nvptx64-nvidia-cuda +//[all-z]~? ERROR `-C stack-protector=all` is not supported for target nvptx64-nvidia-cuda +//[strong]~? ERROR `-C stack-protector=strong` is not supported for target nvptx64-nvidia-cuda diff --git a/tests/ui/stack-protector/fail-stack-protector-unsupported.strong.stderr b/tests/ui/stack-protector/fail-stack-protector-unsupported.strong.stderr new file mode 100644 index 0000000000000..a92575e597af8 --- /dev/null +++ b/tests/ui/stack-protector/fail-stack-protector-unsupported.strong.stderr @@ -0,0 +1,4 @@ +error: `-C stack-protector=strong` is not supported for target nvptx64-nvidia-cuda + +error: aborting due to 1 previous error + diff --git a/tests/ui/stack-protector/warn-stack-protector-unsupported.all.stderr b/tests/ui/stack-protector/warn-stack-protector-unsupported.all.stderr deleted file mode 100644 index 54887715523c1..0000000000000 --- a/tests/ui/stack-protector/warn-stack-protector-unsupported.all.stderr +++ /dev/null @@ -1,4 +0,0 @@ -warning: `-Z stack-protector=all` is not supported for target nvptx64-nvidia-cuda and will be ignored - -warning: 1 warning emitted - diff --git a/tests/ui/stack-protector/warn-stack-protector-unsupported.basic.stderr b/tests/ui/stack-protector/warn-stack-protector-unsupported.basic.stderr deleted file mode 100644 index f7a1ee39fb9af..0000000000000 --- a/tests/ui/stack-protector/warn-stack-protector-unsupported.basic.stderr +++ /dev/null @@ -1,4 +0,0 @@ -warning: `-Z stack-protector=basic` is not supported for target nvptx64-nvidia-cuda and will be ignored - -warning: 1 warning emitted - diff --git a/tests/ui/stack-protector/warn-stack-protector-unsupported.strong.stderr b/tests/ui/stack-protector/warn-stack-protector-unsupported.strong.stderr deleted file mode 100644 index ccc2f9f2cc5b8..0000000000000 --- a/tests/ui/stack-protector/warn-stack-protector-unsupported.strong.stderr +++ /dev/null @@ -1,4 +0,0 @@ -warning: `-Z stack-protector=strong` is not supported for target nvptx64-nvidia-cuda and will be ignored - -warning: 1 warning emitted - From 9c8e2dfa11559a3ce6e19275907ccd9da98198e5 Mon Sep 17 00:00:00 2001 From: Ariel Ben-Yehuda Date: Tue, 9 Sep 2025 11:26:18 +0000 Subject: [PATCH 2/9] remove stack-protector=basic stack-protector=basic is a heuristic designed for C putting this in its own commit to allow for easy reversion if someone wants it --- bootstrap.example.toml | 3 +-- compiler/rustc_codegen_llvm/src/attributes.rs | 1 - compiler/rustc_codegen_llvm/src/lib.rs | 14 ----------- compiler/rustc_interface/src/tests.rs | 3 ++- compiler/rustc_target/src/spec/mod.rs | 6 ----- src/doc/rustc/src/codegen-options/index.md | 2 -- ...otector-heuristics-effect-windows-32bit.rs | 23 +++++-------------- ...otector-heuristics-effect-windows-64bit.rs | 22 ++++-------------- .../stack-protector-heuristics-effect.rs | 21 ++++------------- tests/codegen-llvm/stack-protector.rs | 14 ----------- .../no-stack-protector-basic.rs | 9 ++++++++ .../no-stack-protector-basic.stable.stderr | 2 ++ .../no-stack-protector-basic.unstable.stderr | 2 ++ 13 files changed, 30 insertions(+), 92 deletions(-) create mode 100644 tests/ui/stack-protector/no-stack-protector-basic.rs create mode 100644 tests/ui/stack-protector/no-stack-protector-basic.stable.stderr create mode 100644 tests/ui/stack-protector/no-stack-protector-basic.unstable.stderr diff --git a/bootstrap.example.toml b/bootstrap.example.toml index 1be2bef14eb85..7e8053e997ad8 100644 --- a/bootstrap.example.toml +++ b/bootstrap.example.toml @@ -729,8 +729,7 @@ # Indicates whether stack protectors should be used # via `-Cstack-protector`. # -# Valid options are : `none`(default),`basic`,`strong`, or `all`. -# `strong` and `basic` options may be buggy and are not recommended, see rust-lang/rust#114903. +# Valid options are : `none`(default), `strong`, or `all`. #rust.stack-protector = "none" # Prints each test name as it is executed, to help debug issues in the test harness itself. diff --git a/compiler/rustc_codegen_llvm/src/attributes.rs b/compiler/rustc_codegen_llvm/src/attributes.rs index a25ce9e5a90ac..9a8ae738e15a0 100644 --- a/compiler/rustc_codegen_llvm/src/attributes.rs +++ b/compiler/rustc_codegen_llvm/src/attributes.rs @@ -294,7 +294,6 @@ fn stackprotector_attr<'ll>(cx: &SimpleCx<'ll>, sess: &Session) -> Option<&'ll A StackProtector::None => return None, StackProtector::All => AttributeKind::StackProtectReq, StackProtector::Strong => AttributeKind::StackProtectStrong, - StackProtector::Basic => AttributeKind::StackProtect, }; Some(sspattr.create_attr(cx.llcx)) diff --git a/compiler/rustc_codegen_llvm/src/lib.rs b/compiler/rustc_codegen_llvm/src/lib.rs index a351100e1fea3..f2ce35ba0e2db 100644 --- a/compiler/rustc_codegen_llvm/src/lib.rs +++ b/compiler/rustc_codegen_llvm/src/lib.rs @@ -295,20 +295,6 @@ impl CodegenBackend for LlvmCodegenBackend { *post-optimization*, contain either arrays (of any size or type) or address-taken locals. - basic - Generate stack canaries in functions that are heuristically - suspected to contain buffer overflows. - - The heuristic is subject to change, but currently it - includes functions with local variables of `[T; N]` - type, where `T` is byte-sized and `N` >= 8. - - This heuristic originated from C, where it detects - functions that allocate a `char buf[N];` buffer on the - stack, and are therefore likely to have a stack buffer overflow - in the case of a length-calculation error. It is *not* a good - heuristic for Rust code. - none Do not generate stack canaries. "# diff --git a/compiler/rustc_interface/src/tests.rs b/compiler/rustc_interface/src/tests.rs index 136ef871942af..eaa2ab89ca610 100644 --- a/compiler/rustc_interface/src/tests.rs +++ b/compiler/rustc_interface/src/tests.rs @@ -641,7 +641,7 @@ fn test_codegen_options_tracking_hash() { tracked!(relro_level, Some(RelroLevel::Full)); tracked!(soft_float, true); tracked!(split_debuginfo, Some(SplitDebuginfo::Packed)); - tracked!(stack_protector, StackProtector::All); + tracked!(stack_protector, Some(StackProtector::All)); tracked!(symbol_mangling_version, Some(SymbolManglingVersion::V0)); tracked!(target_cpu, Some(String::from("abc"))); tracked!(target_feature, String::from("all the features, all of them")); @@ -872,6 +872,7 @@ fn test_unstable_options_tracking_hash() { tracked!(small_data_threshold, Some(16)); tracked!(split_lto_unit, Some(true)); tracked!(src_hash_algorithm, Some(SourceFileHashAlgorithm::Sha1)); + tracked!(stack_protector, Some(StackProtector::All)); tracked!(teach, true); tracked!(thinlto, Some(true)); tracked!(tiny_const_eval_limit, true); diff --git a/compiler/rustc_target/src/spec/mod.rs b/compiler/rustc_target/src/spec/mod.rs index c76e345bb7b64..5f5e992879c2c 100644 --- a/compiler/rustc_target/src/spec/mod.rs +++ b/compiler/rustc_target/src/spec/mod.rs @@ -1340,12 +1340,6 @@ crate::target_spec_enum! { /// Disable stack canary generation. None = "none", - /// On LLVM, mark all generated LLVM functions with the `ssp` attribute (see - /// llvm/docs/LangRef.rst). This triggers stack canary generation in - /// functions which contain an array of a byte-sized type with more than - /// eight elements. - Basic = "basic", - /// On LLVM, mark all generated LLVM functions with the `sspstrong` /// attribute (see llvm/docs/LangRef.rst). This triggers stack canary /// generation in functions which either contain an array, or which take diff --git a/src/doc/rustc/src/codegen-options/index.md b/src/doc/rustc/src/codegen-options/index.md index 57bd3f3e0b316..9924e35941e55 100644 --- a/src/doc/rustc/src/codegen-options/index.md +++ b/src/doc/rustc/src/codegen-options/index.md @@ -705,8 +705,6 @@ This flag controls stack smashing protection strategy. Supported values for this option are: - `none` (default): Disable stack canary generation -- `basic`: Generate stack canaries in functions that are suspected - to have a high chance of containing stack buffer overflows (deprecated). - `strong`: Generate stack canaries in all functions, unless the compiler can prove these functions can't be the source of a stack buffer overflow (even in the presence of undefined behavior). diff --git a/tests/assembly-llvm/stack-protector/stack-protector-heuristics-effect-windows-32bit.rs b/tests/assembly-llvm/stack-protector/stack-protector-heuristics-effect-windows-32bit.rs index 0d7a5453cc19d..89be2bb5ebc2c 100644 --- a/tests/assembly-llvm/stack-protector/stack-protector-heuristics-effect-windows-32bit.rs +++ b/tests/assembly-llvm/stack-protector/stack-protector-heuristics-effect-windows-32bit.rs @@ -1,11 +1,10 @@ -//@ revisions: all strong basic none missing +//@ revisions: all strong none missing //@ assembly-output: emit-asm //@ only-windows //@ only-msvc //@ ignore-64bit 64-bit table based SEH has slightly different behaviors than classic SEH //@ [all] compile-flags: -C stack-protector=all //@ [strong] compile-flags: -C stack-protector=strong -//@ [basic] compile-flags: -C stack-protector=basic //@ [none] compile-flags: -C stack-protector=none //@ compile-flags: -C opt-level=2 -Z merge-functions=disabled @@ -18,7 +17,6 @@ pub fn emptyfn() { // all: __security_check_cookie // strong-NOT: __security_check_cookie - // basic-NOT: __security_check_cookie // none-NOT: __security_check_cookie // missing-NOT: __security_check_cookie } @@ -36,7 +34,6 @@ pub fn array_char(f: fn(*const char)) { // all: __security_check_cookie // strong: __security_check_cookie - // basic: __security_check_cookie // none-NOT: __security_check_cookie // missing-NOT: __security_check_cookie } @@ -52,7 +49,6 @@ pub fn array_u8_1(f: fn(*const u8)) { // all: __security_check_cookie // strong: __security_check_cookie - // basic-NOT: __security_check_cookie // none-NOT: __security_check_cookie // missing-NOT: __security_check_cookie } @@ -66,10 +62,10 @@ pub fn array_u8_small(f: fn(*const u8)) { f(&b as *const _); // Small arrays do not lead to stack protection by the 'basic' heuristic. + // (basic is not currently supported, leaving the test anyway). // all: __security_check_cookie // strong: __security_check_cookie - // basic-NOT: __security_check_cookie // none-NOT: __security_check_cookie // missing-NOT: __security_check_cookie } @@ -82,10 +78,10 @@ pub fn array_u8_large(f: fn(*const u8)) { // Since `a` is a byte array with size greater than 8, the basic heuristic // will also protect this function. + // (basic is not currently supported, leaving the test anyway). // all: __security_check_cookie // strong: __security_check_cookie - // basic: __security_check_cookie // none-NOT: __security_check_cookie // missing-NOT: __security_check_cookie } @@ -101,10 +97,10 @@ pub fn array_bytesizednewtype_9(f: fn(*const ByteSizedNewtype)) { // Since `a` is a byte array in the LLVM output, the basic heuristic will // also protect this function. + // (basic is not currently supported, leaving the test anyway). // all: __security_check_cookie // strong: __security_check_cookie - // basic: __security_check_cookie // none-NOT: __security_check_cookie // missing-NOT: __security_check_cookie } @@ -128,10 +124,10 @@ pub fn local_var_addr_used_indirectly(f: fn(bool)) { // } // EOF // ``` + // (basic is not currently supported, leaving the test anyway). // all: __security_check_cookie // strong: __security_check_cookie - // basic-NOT: __security_check_cookie // none-NOT: __security_check_cookie // missing-NOT: __security_check_cookie } @@ -159,10 +155,10 @@ pub fn local_string_addr_taken(f: fn(&String)) { // EOF // ``` // + // (basic is not currently supported, leaving the test anyway). // all: __security_check_cookie // strong-NOT: __security_check_cookie - // basic-NOT: __security_check_cookie // none-NOT: __security_check_cookie // missing-NOT: __security_check_cookie } @@ -191,7 +187,6 @@ pub fn local_var_addr_taken_used_locally_only(factory: fn() -> i32, sink: fn(i32 // all: __security_check_cookie // strong-NOT: __security_check_cookie - // basic-NOT: __security_check_cookie // none-NOT: __security_check_cookie // missing-NOT: __security_check_cookie } @@ -228,7 +223,6 @@ pub fn local_large_var_moved(f: fn(Gigastruct)) { // all: __security_check_cookie // strong: __security_check_cookie - // basic: __security_check_cookie // none-NOT: __security_check_cookie // missing-NOT: __security_check_cookie } @@ -257,7 +251,6 @@ pub fn local_large_var_cloned(f: fn(Gigastruct)) { // all: __security_check_cookie // strong: __security_check_cookie - // basic: __security_check_cookie // none-NOT: __security_check_cookie // missing-NOT: __security_check_cookie } @@ -297,7 +290,6 @@ pub fn alloca_small_compile_time_constant_arg(f: fn(*mut ())) { // all: __security_check_cookie // strong-NOT: __security_check_cookie - // basic-NOT: __security_check_cookie // none-NOT: __security_check_cookie // missing-NOT: __security_check_cookie } @@ -309,7 +301,6 @@ pub fn alloca_large_compile_time_constant_arg(f: fn(*mut ())) { // all: __security_check_cookie // strong-NOT: __security_check_cookie - // basic-NOT: __security_check_cookie // none-NOT: __security_check_cookie // missing-NOT: __security_check_cookie } @@ -321,7 +312,6 @@ pub fn alloca_dynamic_arg(f: fn(*mut ()), n: usize) { // all: __security_check_cookie // strong-NOT: __security_check_cookie - // basic-NOT: __security_check_cookie // none-NOT: __security_check_cookie // missing-NOT: __security_check_cookie } @@ -353,7 +343,6 @@ pub fn unsized_fn_param(s: [u8], l: bool, f: fn([u8])) { // all-NOT: __security_check_cookie // strong-NOT: __security_check_cookie - // basic-NOT: __security_check_cookie // none-NOT: __security_check_cookie // missing-NOT: __security_check_cookie } diff --git a/tests/assembly-llvm/stack-protector/stack-protector-heuristics-effect-windows-64bit.rs b/tests/assembly-llvm/stack-protector/stack-protector-heuristics-effect-windows-64bit.rs index db592fc3ec770..bbd0a2918532d 100644 --- a/tests/assembly-llvm/stack-protector/stack-protector-heuristics-effect-windows-64bit.rs +++ b/tests/assembly-llvm/stack-protector/stack-protector-heuristics-effect-windows-64bit.rs @@ -1,11 +1,10 @@ -//@ revisions: all strong basic none missing +//@ revisions: all strong none missing //@ assembly-output: emit-asm //@ only-windows //@ only-msvc //@ ignore-32bit 64-bit table based SEH has slightly different behaviors than classic SEH //@ [all] compile-flags: -C stack-protector=all //@ [strong] compile-flags: -C stack-protector=strong -//@ [basic] compile-flags: -C stack-protector=basic //@ [none] compile-flags: -C stack-protector=none //@ compile-flags: -C opt-level=2 -Z merge-functions=disabled @@ -17,7 +16,6 @@ pub fn emptyfn() { // all: __security_check_cookie // strong-NOT: __security_check_cookie - // basic-NOT: __security_check_cookie // none-NOT: __security_check_cookie // missing-NOT: __security_check_cookie } @@ -35,7 +33,6 @@ pub fn array_char(f: fn(*const char)) { // all: __security_check_cookie // strong: __security_check_cookie - // basic: __security_check_cookie // none-NOT: __security_check_cookie // missing-NOT: __security_check_cookie } @@ -51,7 +48,6 @@ pub fn array_u8_1(f: fn(*const u8)) { // all: __security_check_cookie // strong: __security_check_cookie - // basic-NOT: __security_check_cookie // none-NOT: __security_check_cookie // missing-NOT: __security_check_cookie } @@ -65,10 +61,10 @@ pub fn array_u8_small(f: fn(*const u8)) { f(&b as *const _); // Small arrays do not lead to stack protection by the 'basic' heuristic. + // (basic is not currently supported, leaving the test anyway). // all: __security_check_cookie // strong: __security_check_cookie - // basic-NOT: __security_check_cookie // none-NOT: __security_check_cookie // missing-NOT: __security_check_cookie } @@ -81,10 +77,10 @@ pub fn array_u8_large(f: fn(*const u8)) { // Since `a` is a byte array with size greater than 8, the basic heuristic // will also protect this function. + // (basic is not currently supported, leaving the test anyway). // all: __security_check_cookie // strong: __security_check_cookie - // basic: __security_check_cookie // none-NOT: __security_check_cookie // missing-NOT: __security_check_cookie } @@ -100,10 +96,10 @@ pub fn array_bytesizednewtype_9(f: fn(*const ByteSizedNewtype)) { // Since `a` is a byte array in the LLVM output, the basic heuristic will // also protect this function. + // (basic is not currently supported, leaving the test anyway). // all: __security_check_cookie // strong: __security_check_cookie - // basic: __security_check_cookie // none-NOT: __security_check_cookie // missing-NOT: __security_check_cookie } @@ -130,7 +126,6 @@ pub fn local_var_addr_used_indirectly(f: fn(bool)) { // all: __security_check_cookie // strong: __security_check_cookie - // basic-NOT: __security_check_cookie // none-NOT: __security_check_cookie // missing-NOT: __security_check_cookie } @@ -158,7 +153,6 @@ pub fn local_string_addr_taken(f: fn(&String)) { // } // EOF // ``` - // // We should have a __security_check_cookie call in `all` and `strong` modes but // LLVM does not support generating stack protectors in functions with funclet @@ -167,7 +161,6 @@ pub fn local_string_addr_taken(f: fn(&String)) { // all-NOT: __security_check_cookie // strong-NOT: __security_check_cookie - // basic-NOT: __security_check_cookie // none-NOT: __security_check_cookie // missing-NOT: __security_check_cookie @@ -198,7 +191,6 @@ pub fn local_var_addr_taken_used_locally_only(factory: fn() -> i32, sink: fn(i32 // all: __security_check_cookie // strong-NOT: __security_check_cookie - // basic-NOT: __security_check_cookie // none-NOT: __security_check_cookie // missing-NOT: __security_check_cookie } @@ -235,7 +227,6 @@ pub fn local_large_var_moved(f: fn(Gigastruct)) { // all: __security_check_cookie // strong: __security_check_cookie - // basic: __security_check_cookie // none-NOT: __security_check_cookie // missing-NOT: __security_check_cookie } @@ -264,7 +255,6 @@ pub fn local_large_var_cloned(f: fn(Gigastruct)) { // all: __security_check_cookie // strong: __security_check_cookie - // basic: __security_check_cookie // none-NOT: __security_check_cookie // missing-NOT: __security_check_cookie } @@ -304,7 +294,6 @@ pub fn alloca_small_compile_time_constant_arg(f: fn(*mut ())) { // all: __security_check_cookie // strong-NOT: __security_check_cookie - // basic-NOT: __security_check_cookie // none-NOT: __security_check_cookie // missing-NOT: __security_check_cookie } @@ -316,7 +305,6 @@ pub fn alloca_large_compile_time_constant_arg(f: fn(*mut ())) { // all: __security_check_cookie // strong-NOT: __security_check_cookie - // basic-NOT: __security_check_cookie // none-NOT: __security_check_cookie // missing-NOT: __security_check_cookie } @@ -328,7 +316,6 @@ pub fn alloca_dynamic_arg(f: fn(*mut ()), n: usize) { // all: __security_check_cookie // strong-NOT: __security_check_cookie - // basic-NOT: __security_check_cookie // none-NOT: __security_check_cookie // missing-NOT: __security_check_cookie } @@ -360,7 +347,6 @@ pub fn unsized_fn_param(s: [u8], l: bool, f: fn([u8])) { // all-NOT: __security_check_cookie // strong-NOT: __security_check_cookie - // basic-NOT: __security_check_cookie // none-NOT: __security_check_cookie // missing-NOT: __security_check_cookie } diff --git a/tests/assembly-llvm/stack-protector/stack-protector-heuristics-effect.rs b/tests/assembly-llvm/stack-protector/stack-protector-heuristics-effect.rs index 31a31a807a613..4b78a643b7b7b 100644 --- a/tests/assembly-llvm/stack-protector/stack-protector-heuristics-effect.rs +++ b/tests/assembly-llvm/stack-protector/stack-protector-heuristics-effect.rs @@ -1,4 +1,4 @@ -//@ revisions: all strong basic none missing +//@ revisions: all strong none missing //@ assembly-output: emit-asm //@ ignore-apple slightly different policy on stack protection of arrays //@ ignore-msvc stack check code uses different function names @@ -6,7 +6,6 @@ //@ ignore-wasm32-unknown-unknown //@ [all] compile-flags: -C stack-protector=all //@ [strong] compile-flags: -C stack-protector=strong -//@ [basic] compile-flags: -C stack-protector=basic //@ [none] compile-flags: -C stack-protector=none //@ compile-flags: -C opt-level=2 -Z merge-functions=disabled @@ -24,7 +23,6 @@ pub fn emptyfn() { // all: __stack_chk_fail // strong-NOT: __stack_chk_fail - // basic-NOT: __stack_chk_fail // none-NOT: __stack_chk_fail // missing-NOT: __stack_chk_fail } @@ -42,7 +40,6 @@ pub fn array_char(f: fn(*const char)) { // all: __stack_chk_fail // strong: __stack_chk_fail - // basic: __stack_chk_fail // none-NOT: __stack_chk_fail // missing-NOT: __stack_chk_fail } @@ -58,7 +55,6 @@ pub fn array_u8_1(f: fn(*const u8)) { // all: __stack_chk_fail // strong: __stack_chk_fail - // basic-NOT: __stack_chk_fail // none-NOT: __stack_chk_fail // missing-NOT: __stack_chk_fail } @@ -72,10 +68,10 @@ pub fn array_u8_small(f: fn(*const u8)) { f(&b as *const _); // Small arrays do not lead to stack protection by the 'basic' heuristic. + // (basic is not currently supported, leaving the test anyway). // all: __stack_chk_fail // strong: __stack_chk_fail - // basic-NOT: __stack_chk_fail // none-NOT: __stack_chk_fail // missing-NOT: __stack_chk_fail } @@ -88,10 +84,10 @@ pub fn array_u8_large(f: fn(*const u8)) { // Since `a` is a byte array with size greater than 8, the basic heuristic // will also protect this function. + // (basic is not currently supported, leaving the test anyway). // all: __stack_chk_fail // strong: __stack_chk_fail - // basic: __stack_chk_fail // none-NOT: __stack_chk_fail // missing-NOT: __stack_chk_fail } @@ -107,10 +103,10 @@ pub fn array_bytesizednewtype_9(f: fn(*const ByteSizedNewtype)) { // Since `a` is a byte array in the LLVM output, the basic heuristic will // also protect this function. + // (basic is not currently supported, leaving the test anyway). // all: __stack_chk_fail // strong: __stack_chk_fail - // basic: __stack_chk_fail // none-NOT: __stack_chk_fail // missing-NOT: __stack_chk_fail } @@ -137,7 +133,6 @@ pub fn local_var_addr_used_indirectly(f: fn(bool)) { // all: __stack_chk_fail // strong: __stack_chk_fail - // basic-NOT: __stack_chk_fail // none-NOT: __stack_chk_fail // missing-NOT: __stack_chk_fail } @@ -153,7 +148,6 @@ pub fn local_string_addr_taken(f: fn(&String)) { // all: __stack_chk_fail // strong: __stack_chk_fail - // basic: __stack_chk_fail // none-NOT: __stack_chk_fail // missing-NOT: __stack_chk_fail } @@ -182,7 +176,6 @@ pub fn local_var_addr_taken_used_locally_only(factory: fn() -> i32, sink: fn(i32 // all: __stack_chk_fail // strong-NOT: __stack_chk_fail - // basic-NOT: __stack_chk_fail // none-NOT: __stack_chk_fail // missing-NOT: __stack_chk_fail } @@ -219,7 +212,6 @@ pub fn local_large_var_moved(f: fn(Gigastruct)) { // all: __stack_chk_fail // strong: __stack_chk_fail - // basic: __stack_chk_fail // none-NOT: __stack_chk_fail // missing-NOT: __stack_chk_fail } @@ -248,7 +240,6 @@ pub fn local_large_var_cloned(f: fn(Gigastruct)) { // all: __stack_chk_fail // strong: __stack_chk_fail - // basic: __stack_chk_fail // none-NOT: __stack_chk_fail // missing-NOT: __stack_chk_fail } @@ -288,7 +279,6 @@ pub fn alloca_small_compile_time_constant_arg(f: fn(*mut ())) { // all: __stack_chk_fail // strong-NOT: __stack_chk_fail - // basic-NOT: __stack_chk_fail // none-NOT: __stack_chk_fail // missing-NOT: __stack_chk_fail } @@ -300,7 +290,6 @@ pub fn alloca_large_compile_time_constant_arg(f: fn(*mut ())) { // all: __stack_chk_fail // strong-NOT: __stack_chk_fail - // basic-NOT: __stack_chk_fail // none-NOT: __stack_chk_fail // missing-NOT: __stack_chk_fail } @@ -312,7 +301,6 @@ pub fn alloca_dynamic_arg(f: fn(*mut ()), n: usize) { // all: __stack_chk_fail // strong-NOT: __stack_chk_fail - // basic-NOT: __stack_chk_fail // none-NOT: __stack_chk_fail // missing-NOT: __stack_chk_fail } @@ -339,7 +327,6 @@ pub fn unsized_fn_param(s: [u8], l: bool, f: fn([u8])) { // all: __stack_chk_fail // strong-NOT: __stack_chk_fail - // basic-NOT: __stack_chk_fail // none-NOT: __stack_chk_fail // missing-NOT: __stack_chk_fail } diff --git a/tests/codegen-llvm/stack-protector.rs b/tests/codegen-llvm/stack-protector.rs index 686db3f1f4412..1477d2ed7b28a 100644 --- a/tests/codegen-llvm/stack-protector.rs +++ b/tests/codegen-llvm/stack-protector.rs @@ -4,8 +4,6 @@ //@ [all-z] compile-flags: -Z stack-protector=all //@ [strong] compile-flags: -C stack-protector=strong //@ [strong-z] compile-flags: -Z stack-protector=strong -//@ [basic] compile-flags: -C stack-protector=basic -//@ [basic-z] compile-flags: -Z stack-protector=basic //@ [strong-c-overrides-z] compile-flags: -C stack-protector=strong -Z stack-protector=all #![crate_type = "lib"] @@ -44,18 +42,6 @@ pub fn foo() { // strong-c-overrides-z-NOT: attributes #0 = { {{.*}}sspreq {{.*}} } // strong-c-overrides-z-NOT: attributes #0 = { {{.*}}ssp {{.*}} } - // basic-NOT: attributes #0 = { {{.*}}sspreq {{.*}} } - // basic-NOT: attributes #0 = { {{.*}}sspstrong {{.*}} } - // basic: attributes #0 = { {{.*}}ssp {{.*}} } - // basic-NOT: attributes #0 = { {{.*}}sspreq {{.*}} } - // basic-NOT: attributes #0 = { {{.*}}sspstrong {{.*}} } - - // basic-z-NOT: attributes #0 = { {{.*}}sspreq {{.*}} } - // basic-z-NOT: attributes #0 = { {{.*}}sspstrong {{.*}} } - // basic-z: attributes #0 = { {{.*}}ssp {{.*}} } - // basic-z-NOT: attributes #0 = { {{.*}}sspreq {{.*}} } - // basic-z-NOT: attributes #0 = { {{.*}}sspstrong {{.*}} } - // none-NOT: attributes #0 = { {{.*}}sspreq {{.*}} } // none-NOT: attributes #0 = { {{.*}}sspstrong {{.*}} } // none-NOT: attributes #0 = { {{.*}}ssp {{.*}} } diff --git a/tests/ui/stack-protector/no-stack-protector-basic.rs b/tests/ui/stack-protector/no-stack-protector-basic.rs new file mode 100644 index 0000000000000..80f0e9b5d8c38 --- /dev/null +++ b/tests/ui/stack-protector/no-stack-protector-basic.rs @@ -0,0 +1,9 @@ +//@ check-fail +//@ revisions: stable unstable +//@ [unstable] compile-flags: -Z stack-protector=basic +//@ [stable] compile-flags: -C stack-protector=basic + +pub fn main(){} + +//[unstable]~? ERROR incorrect value `basic` for unstable option `stack-protector` +//[stable]~? ERROR incorrect value `basic` for codegen option `stack-protector` diff --git a/tests/ui/stack-protector/no-stack-protector-basic.stable.stderr b/tests/ui/stack-protector/no-stack-protector-basic.stable.stderr new file mode 100644 index 0000000000000..7295a2e9bd45a --- /dev/null +++ b/tests/ui/stack-protector/no-stack-protector-basic.stable.stderr @@ -0,0 +1,2 @@ +error: incorrect value `basic` for codegen option `stack-protector` - one of (`none` (default), `basic`, `strong`, or `all`) was expected + diff --git a/tests/ui/stack-protector/no-stack-protector-basic.unstable.stderr b/tests/ui/stack-protector/no-stack-protector-basic.unstable.stderr new file mode 100644 index 0000000000000..ce88114f16b82 --- /dev/null +++ b/tests/ui/stack-protector/no-stack-protector-basic.unstable.stderr @@ -0,0 +1,2 @@ +error: incorrect value `basic` for unstable option `stack-protector` - one of (`none` (default), `basic`, `strong`, or `all`) was expected + From 50a5f5eff3b8bdfca940275351ea8ad5076abd4b Mon Sep 17 00:00:00 2001 From: Ariel Ben-Yehuda Date: Tue, 9 Sep 2025 13:39:48 +0000 Subject: [PATCH 3/9] change wording for stack-protector-strong --- compiler/rustc_codegen_llvm/src/lib.rs | 6 ++++-- src/doc/rustc/src/codegen-options/index.md | 8 +++++--- 2 files changed, 9 insertions(+), 5 deletions(-) diff --git a/compiler/rustc_codegen_llvm/src/lib.rs b/compiler/rustc_codegen_llvm/src/lib.rs index f2ce35ba0e2db..ce613f7e195f5 100644 --- a/compiler/rustc_codegen_llvm/src/lib.rs +++ b/compiler/rustc_codegen_llvm/src/lib.rs @@ -292,8 +292,10 @@ impl CodegenBackend for LlvmCodegenBackend { The exact rules are unstable and subject to change, but currently, it generates stack protectors for functions that, - *post-optimization*, contain either arrays (of any size - or type) or address-taken locals. + *post-optimization*, contain LLVM allocas (which + include all stack allocations - including fixed-size + allocations - that are used in a way that is not completely + determined by static control flow). none Do not generate stack canaries. diff --git a/src/doc/rustc/src/codegen-options/index.md b/src/doc/rustc/src/codegen-options/index.md index 9924e35941e55..d360781aac69c 100644 --- a/src/doc/rustc/src/codegen-options/index.md +++ b/src/doc/rustc/src/codegen-options/index.md @@ -714,9 +714,11 @@ Supported values for this option are: The exact rules are unstable and subject to change, but currently, it generates stack protectors for functions that, - *post-optimization*, contain either arrays (of any size - or type) or address-taken locals. -- `all`: Generate stack canaries in all functions + *post-optimization*, contain LLVM allocas (which + include all stack allocations - including fixed-size + allocations - that are used in a way that is not completely + determined by static control flow). + - `all`: Generate stack canaries in all functions Stack protectors are not supported on many GPU targets, use of stack protectors on these targets is an error. From 7ea7c3dfae9df3f2d5e9813894b10b7a9788031c Mon Sep 17 00:00:00 2001 From: Ariel Ben-Yehuda Date: Tue, 9 Sep 2025 16:31:34 +0000 Subject: [PATCH 4/9] similar security guarnatees rather than exactly --- compiler/rustc_codegen_llvm/src/lib.rs | 2 +- src/doc/rustc/src/codegen-options/index.md | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/compiler/rustc_codegen_llvm/src/lib.rs b/compiler/rustc_codegen_llvm/src/lib.rs index ce613f7e195f5..5df966d644c79 100644 --- a/compiler/rustc_codegen_llvm/src/lib.rs +++ b/compiler/rustc_codegen_llvm/src/lib.rs @@ -287,7 +287,7 @@ impl CodegenBackend for LlvmCodegenBackend { can prove these functions can't be the source of a stack buffer overflow (even in the presence of undefined behavior). - This provides the same security guarantees as Clang's + This provides similar security guarantees to Clang's `-fstack-protector=strong`. The exact rules are unstable and subject to change, but diff --git a/src/doc/rustc/src/codegen-options/index.md b/src/doc/rustc/src/codegen-options/index.md index d360781aac69c..a193b71c27df2 100644 --- a/src/doc/rustc/src/codegen-options/index.md +++ b/src/doc/rustc/src/codegen-options/index.md @@ -709,7 +709,7 @@ Supported values for this option are: can prove these functions can't be the source of a stack buffer overflow (even in the presence of undefined behavior). - This provides the same security guarantees as Clang's + This provides similar security guarantees to Clang's `-fstack-protector=strong`. The exact rules are unstable and subject to change, but From 2d16d247740b70728d5f150f8ac6d28502dec8ce Mon Sep 17 00:00:00 2001 From: Ariel Ben-Yehuda Date: Wed, 10 Sep 2025 10:41:40 +0000 Subject: [PATCH 5/9] stack smash protection => stack smashing protection --- compiler/rustc_session/src/options.rs | 4 ++-- .../stack-protector-heuristics-effect-windows-32bit.rs | 4 ++-- .../stack-protector-heuristics-effect-windows-64bit.rs | 4 ++-- .../stack-protector/stack-protector-heuristics-effect.rs | 6 +++--- .../stack-protector/stack-protector-target-support.rs | 2 +- 5 files changed, 10 insertions(+), 10 deletions(-) diff --git a/compiler/rustc_session/src/options.rs b/compiler/rustc_session/src/options.rs index 1034126bcffbd..4ef08d4f9922a 100644 --- a/compiler/rustc_session/src/options.rs +++ b/compiler/rustc_session/src/options.rs @@ -2188,7 +2188,7 @@ options! { "how to handle split-debuginfo, a platform-specific option"), #[rustc_lint_opt_deny_field_access("use `Session::stack_protector` instead of this field")] stack_protector: Option = (None, parse_stack_protector, [TRACKED], - "control stack smash protection strategy (`rustc --print stack-protector-strategies` for details)"), + "control stack smashing protection strategy (`rustc --print stack-protector-strategies` for details)"), strip: Strip = (Strip::None, parse_strip, [UNTRACKED], "tell the linker which information to strip (`none` (default), `debuginfo` or `symbols`)"), symbol_mangling_version: Option = (None, @@ -2666,7 +2666,7 @@ written to standard error output)"), "hash algorithm of source files in debug info (`md5`, `sha1`, or `sha256`)"), #[rustc_lint_opt_deny_field_access("use `Session::stack_protector` instead of this field")] stack_protector: Option = (None, parse_stack_protector, [TRACKED], - "control stack smash protection strategy (`rustc --print stack-protector-strategies` for details)"), + "control stack smashing protection strategy (`rustc --print stack-protector-strategies` for details)"), staticlib_allow_rdylib_deps: bool = (false, parse_bool, [TRACKED], "allow staticlibs to have rust dylib dependencies"), staticlib_prefer_dynamic: bool = (false, parse_bool, [TRACKED], diff --git a/tests/assembly-llvm/stack-protector/stack-protector-heuristics-effect-windows-32bit.rs b/tests/assembly-llvm/stack-protector/stack-protector-heuristics-effect-windows-32bit.rs index 89be2bb5ebc2c..95661b6894131 100644 --- a/tests/assembly-llvm/stack-protector/stack-protector-heuristics-effect-windows-32bit.rs +++ b/tests/assembly-llvm/stack-protector/stack-protector-heuristics-effect-windows-32bit.rs @@ -114,7 +114,7 @@ pub fn local_var_addr_used_indirectly(f: fn(bool)) { // This function takes the address of a local variable taken. Although this // address is never used as a way to refer to stack memory, the `strong` - // heuristic adds stack smash protection. This is also the case in C++: + // heuristic adds stack smashing protection. This is also the case in C++: // ``` // cat << EOF | clang++ -O2 -fstack-protector-strong -S -x c++ - -o - | grep stack_chk // #include @@ -182,7 +182,7 @@ pub fn local_var_addr_taken_used_locally_only(factory: fn() -> i32, sink: fn(i32 // Even though the local variable conceptually has its address taken, as // it's passed by reference to the trait function, the use of the reference - // is easily inlined. There is therefore no stack smash protection even with + // is easily inlined. There is therefore no stack smashing protection even with // the `strong` heuristic. // all: __security_check_cookie diff --git a/tests/assembly-llvm/stack-protector/stack-protector-heuristics-effect-windows-64bit.rs b/tests/assembly-llvm/stack-protector/stack-protector-heuristics-effect-windows-64bit.rs index bbd0a2918532d..525be324f509c 100644 --- a/tests/assembly-llvm/stack-protector/stack-protector-heuristics-effect-windows-64bit.rs +++ b/tests/assembly-llvm/stack-protector/stack-protector-heuristics-effect-windows-64bit.rs @@ -113,7 +113,7 @@ pub fn local_var_addr_used_indirectly(f: fn(bool)) { // This function takes the address of a local variable taken. Although this // address is never used as a way to refer to stack memory, the `strong` - // heuristic adds stack smash protection. This is also the case in C++: + // heuristic adds stack smashing protection. This is also the case in C++: // ``` // cat << EOF | clang++ -O2 -fstack-protector-strong -S -x c++ - -o - | grep stack_chk // #include @@ -186,7 +186,7 @@ pub fn local_var_addr_taken_used_locally_only(factory: fn() -> i32, sink: fn(i32 // Even though the local variable conceptually has its address taken, as // it's passed by reference to the trait function, the use of the reference - // is easily inlined. There is therefore no stack smash protection even with + // is easily inlined. There is therefore no stack smashing protection even with // the `strong` heuristic. // all: __security_check_cookie diff --git a/tests/assembly-llvm/stack-protector/stack-protector-heuristics-effect.rs b/tests/assembly-llvm/stack-protector/stack-protector-heuristics-effect.rs index 4b78a643b7b7b..f508896d7eb97 100644 --- a/tests/assembly-llvm/stack-protector/stack-protector-heuristics-effect.rs +++ b/tests/assembly-llvm/stack-protector/stack-protector-heuristics-effect.rs @@ -9,7 +9,7 @@ //@ [none] compile-flags: -C stack-protector=none //@ compile-flags: -C opt-level=2 -Z merge-functions=disabled -// NOTE: the heuristics for stack smash protection inappropriately rely on types in LLVM IR, +// NOTE: the heuristics for stack smashing protection inappropriately rely on types in LLVM IR, // despite those types having no semantic meaning. This means that the `basic` and `strong` // settings do not behave in a coherent way. This is a known issue in LLVM. // See comments on https://github.com/rust-lang/rust/issues/114903. @@ -120,7 +120,7 @@ pub fn local_var_addr_used_indirectly(f: fn(bool)) { // This function takes the address of a local variable taken. Although this // address is never used as a way to refer to stack memory, the `strong` - // heuristic adds stack smash protection. This is also the case in C++: + // heuristic adds stack smashing protection. This is also the case in C++: // ``` // cat << EOF | clang++ -O2 -fstack-protector-strong -S -x c++ - -o - | grep stack_chk // #include @@ -171,7 +171,7 @@ pub fn local_var_addr_taken_used_locally_only(factory: fn() -> i32, sink: fn(i32 // Even though the local variable conceptually has its address taken, as // it's passed by reference to the trait function, the use of the reference - // is easily inlined. There is therefore no stack smash protection even with + // is easily inlined. There is therefore no stack smashing protection even with // the `strong` heuristic. // all: __stack_chk_fail diff --git a/tests/assembly-llvm/stack-protector/stack-protector-target-support.rs b/tests/assembly-llvm/stack-protector/stack-protector-target-support.rs index b10faf233e239..955107589b885 100644 --- a/tests/assembly-llvm/stack-protector/stack-protector-target-support.rs +++ b/tests/assembly-llvm/stack-protector/stack-protector-target-support.rs @@ -1,4 +1,4 @@ -// Test that stack smash protection code is emitted for all tier1 and tier2 +// Test that stack smashing protection code is emitted for all tier1 and tier2 // targets, with the exception of nvptx64-nvidia-cuda // //@ add-minicore From 26612c4b9606042cbc92e8278196eab391f83918 Mon Sep 17 00:00:00 2001 From: Ariel Ben-Yehuda Date: Sat, 13 Sep 2025 15:58:18 +0000 Subject: [PATCH 6/9] add comments for why we dont have basic/plain mode --- compiler/rustc_codegen_llvm/src/lib.rs | 2 +- src/doc/rustc/src/codegen-options/index.md | 11 ++++++++++- 2 files changed, 11 insertions(+), 2 deletions(-) diff --git a/compiler/rustc_codegen_llvm/src/lib.rs b/compiler/rustc_codegen_llvm/src/lib.rs index 5df966d644c79..1f1b22d8a2b1b 100644 --- a/compiler/rustc_codegen_llvm/src/lib.rs +++ b/compiler/rustc_codegen_llvm/src/lib.rs @@ -288,7 +288,7 @@ impl CodegenBackend for LlvmCodegenBackend { buffer overflow (even in the presence of undefined behavior). This provides similar security guarantees to Clang's - `-fstack-protector=strong`. + `-fstack-protector-strong`. The exact rules are unstable and subject to change, but currently, it generates stack protectors for functions that, diff --git a/src/doc/rustc/src/codegen-options/index.md b/src/doc/rustc/src/codegen-options/index.md index a193b71c27df2..3b94827d89ae5 100644 --- a/src/doc/rustc/src/codegen-options/index.md +++ b/src/doc/rustc/src/codegen-options/index.md @@ -710,7 +710,7 @@ Supported values for this option are: buffer overflow (even in the presence of undefined behavior). This provides similar security guarantees to Clang's - `-fstack-protector=strong`. + `-fstack-protector-strong`. The exact rules are unstable and subject to change, but currently, it generates stack protectors for functions that, @@ -720,6 +720,15 @@ Supported values for this option are: determined by static control flow). - `all`: Generate stack canaries in all functions +rustc does not have a mode equivalent to Clang's (or GCC's) +plain `-fstack-protector` - `-fstack-protector` is an older heuristic +designed for C, that only protects functions that allocate a +`char buf[N];` buffer on the stack, making it prone to buffer overflows +from length miscalculations. This heuristic is poorly suited for Rust +code. Even in C codebases, `-fstack-protector-strong` is nowadays +preferred because plain `-fstack-protector` misses many stack +buffer overflows. + Stack protectors are not supported on many GPU targets, use of stack protectors on these targets is an error. From 7c60071567bfb019ac572e2e41f893972c053783 Mon Sep 17 00:00:00 2001 From: Ariel Ben-Yehuda Date: Thu, 20 Nov 2025 15:28:22 +0000 Subject: [PATCH 7/9] remove warn-stack-protector-unsupported since we now fail on it --- .../warn-stack-protector-unsupported.rs | 31 ------------------- 1 file changed, 31 deletions(-) delete mode 100644 tests/ui/stack-protector/warn-stack-protector-unsupported.rs diff --git a/tests/ui/stack-protector/warn-stack-protector-unsupported.rs b/tests/ui/stack-protector/warn-stack-protector-unsupported.rs deleted file mode 100644 index 9e0e126dabe66..0000000000000 --- a/tests/ui/stack-protector/warn-stack-protector-unsupported.rs +++ /dev/null @@ -1,31 +0,0 @@ -//@ build-pass -//@ revisions: all strong basic -//@ compile-flags: --target nvptx64-nvidia-cuda -//@ needs-llvm-components: nvptx -//@ [all] compile-flags: -Z stack-protector=all -//@ [strong] compile-flags: -Z stack-protector=strong -//@ [basic] compile-flags: -Z stack-protector=basic -//@ ignore-backends: gcc - -#![crate_type = "lib"] -#![feature(no_core, lang_items)] -#![no_std] -#![no_core] - -#[lang = "pointee_sized"] -pub trait PointeeSized {} - -#[lang = "meta_sized"] -pub trait MetaSized: PointeeSized {} - -#[lang = "sized"] -trait Sized: MetaSized {} - -#[lang = "copy"] -trait Copy {} - -pub fn main(){} - -//[all]~? WARN `-Z stack-protector=all` is not supported for target nvptx64-nvidia-cuda and will be ignored -//[strong]~? WARN `-Z stack-protector=strong` is not supported for target nvptx64-nvidia-cuda and will be ignored -//[basic]~? WARN `-Z stack-protector=basic` is not supported for target nvptx64-nvidia-cuda and will be ignored From 27cf2c232b519dd717d07ec0c866dee9aa19a555 Mon Sep 17 00:00:00 2001 From: Ariel Ben-Yehuda Date: Thu, 27 Nov 2025 19:28:10 +0000 Subject: [PATCH 8/9] ignore stack-protector test for gcc backend, see commit a8051a6ca37e --- tests/ui/stack-protector/fail-stack-protector-unsupported.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/tests/ui/stack-protector/fail-stack-protector-unsupported.rs b/tests/ui/stack-protector/fail-stack-protector-unsupported.rs index c9eb3560eda42..006c4b1d3a187 100644 --- a/tests/ui/stack-protector/fail-stack-protector-unsupported.rs +++ b/tests/ui/stack-protector/fail-stack-protector-unsupported.rs @@ -5,6 +5,7 @@ //@ [all] compile-flags: -C stack-protector=all //@ [strong] compile-flags: -C stack-protector=strong //@ [all-z] compile-flags: -Z stack-protector=all +//@ ignore-backends: gcc #![crate_type = "lib"] #![feature(no_core, lang_items)] From cca708c07e5717e9825f632574985d582936256c Mon Sep 17 00:00:00 2001 From: Ariel Ben-Yehuda Date: Thu, 11 Dec 2025 15:38:11 +0000 Subject: [PATCH 9/9] fix error message to not mention basic --- compiler/rustc_session/src/options.rs | 3 +-- .../ui/stack-protector/no-stack-protector-basic.stable.stderr | 2 +- .../stack-protector/no-stack-protector-basic.unstable.stderr | 2 +- 3 files changed, 3 insertions(+), 4 deletions(-) diff --git a/compiler/rustc_session/src/options.rs b/compiler/rustc_session/src/options.rs index 4ef08d4f9922a..d5ebe341b4f5e 100644 --- a/compiler/rustc_session/src/options.rs +++ b/compiler/rustc_session/src/options.rs @@ -865,8 +865,7 @@ mod desc { pub(crate) const parse_polonius: &str = "either no value or `legacy` (the default), or `next`"; pub(crate) const parse_annotate_moves: &str = "either a boolean (`yes`, `no`, `on`, `off`, etc.), or a size limit in bytes"; - pub(crate) const parse_stack_protector: &str = - "one of (`none` (default), `basic`, `strong`, or `all`)"; + pub(crate) const parse_stack_protector: &str = "one of (`none` (default), `strong`, or `all`)"; pub(crate) const parse_branch_protection: &str = "a `,` separated combination of `bti`, `gcs`, `pac-ret`, (optionally with `pc`, `b-key`, `leaf` if `pac-ret` is set)"; pub(crate) const parse_proc_macro_execution_strategy: &str = "one of supported execution strategies (`same-thread`, or `cross-thread`)"; diff --git a/tests/ui/stack-protector/no-stack-protector-basic.stable.stderr b/tests/ui/stack-protector/no-stack-protector-basic.stable.stderr index 7295a2e9bd45a..644c3e6a34f2a 100644 --- a/tests/ui/stack-protector/no-stack-protector-basic.stable.stderr +++ b/tests/ui/stack-protector/no-stack-protector-basic.stable.stderr @@ -1,2 +1,2 @@ -error: incorrect value `basic` for codegen option `stack-protector` - one of (`none` (default), `basic`, `strong`, or `all`) was expected +error: incorrect value `basic` for codegen option `stack-protector` - one of (`none` (default), `strong`, or `all`) was expected diff --git a/tests/ui/stack-protector/no-stack-protector-basic.unstable.stderr b/tests/ui/stack-protector/no-stack-protector-basic.unstable.stderr index ce88114f16b82..7ee0f6ae03f3d 100644 --- a/tests/ui/stack-protector/no-stack-protector-basic.unstable.stderr +++ b/tests/ui/stack-protector/no-stack-protector-basic.unstable.stderr @@ -1,2 +1,2 @@ -error: incorrect value `basic` for unstable option `stack-protector` - one of (`none` (default), `basic`, `strong`, or `all`) was expected +error: incorrect value `basic` for unstable option `stack-protector` - one of (`none` (default), `strong`, or `all`) was expected