@@ -19,6 +19,7 @@ pub(crate) struct RustcCodegenFlags<'a> {
19
19
no_redzone : Option < bool > ,
20
20
soft_float : Option < bool > ,
21
21
dwarf_version : Option < u32 > ,
22
+ stack_protector : Option < & ' a str > ,
22
23
}
23
24
24
25
impl < ' this > RustcCodegenFlags < ' this > {
@@ -161,6 +162,12 @@ impl<'this> RustcCodegenFlags<'this> {
161
162
"-Zdwarf-version must have a value" ,
162
163
) ) ?) ;
163
164
}
165
+ // https://github.com/rust-lang/rust/issues/114903
166
+ // FIXME: Drop the -Z variant and update the doc link once the option is stabilized
167
+ "-Zstack-protector" | "-Cstack-protector" => {
168
+ self . stack_protector =
169
+ Some ( flag_ok_or ( value, "-Zstack-protector must have a value" ) ?) ;
170
+ }
164
171
_ => { }
165
172
}
166
173
Ok ( ( ) )
@@ -267,6 +274,23 @@ impl<'this> RustcCodegenFlags<'this> {
267
274
if let Some ( value) = self . dwarf_version {
268
275
push_if_supported ( format ! ( "-gdwarf-{value}" ) . into ( ) ) ;
269
276
}
277
+ // https://clang.llvm.org/docs/ClangCommandLineReference.html#cmdoption-clang-fstack-protector
278
+ // https://gcc.gnu.org/onlinedocs/gcc/Instrumentation-Options.html#index-fstack-protector
279
+ if let Some ( value) = self . stack_protector {
280
+ // don't need to propagate stack-protector on MSVC since /GS is already the default
281
+ // https://learn.microsoft.com/en-us/cpp/build/reference/gs-buffer-security-check?view=msvc-170
282
+ //
283
+ // Do NOT `stack-protector=none` since it weakens security for C code,
284
+ // and `-Zstack-protector=basic` is deprecated and will be removed soon.
285
+ let cc_flag = match value {
286
+ "strong" => Some ( "-fstack-protector-strong" ) ,
287
+ "all" => Some ( "-fstack-protector-all" ) ,
288
+ _ => None ,
289
+ } ;
290
+ if let Some ( cc_flag) = cc_flag {
291
+ push_if_supported ( cc_flag. into ( ) ) ;
292
+ }
293
+ }
270
294
}
271
295
272
296
// Compiler-exclusive flags
@@ -379,6 +403,16 @@ mod tests {
379
403
check ( "-L\u{1f} -Clto" , & expected) ;
380
404
}
381
405
406
+ #[ test]
407
+ fn stack_protector ( ) {
408
+ let expected = RustcCodegenFlags {
409
+ stack_protector : Some ( "strong" ) ,
410
+ ..RustcCodegenFlags :: default ( )
411
+ } ;
412
+ check ( "-Zstack-protector=strong" , & expected) ;
413
+ check ( "-Cstack-protector=strong" , & expected) ;
414
+ }
415
+
382
416
#[ test]
383
417
fn three_valid_prefixes ( ) {
384
418
let expected = RustcCodegenFlags {
@@ -408,6 +442,7 @@ mod tests {
408
442
"-Csoft-float=yes" ,
409
443
"-Zbranch-protection=bti,pac-ret,leaf" ,
410
444
"-Zdwarf-version=5" ,
445
+ "-Zstack-protector=strong" ,
411
446
// Set flags we don't recognise but rustc supports next
412
447
// rustc flags
413
448
"--cfg" ,
@@ -515,6 +550,7 @@ mod tests {
515
550
soft_float : Some ( true ) ,
516
551
branch_protection : Some ( "bti,pac-ret,leaf" ) ,
517
552
dwarf_version : Some ( 5 ) ,
553
+ stack_protector : Some ( "strong" ) ,
518
554
} ,
519
555
) ;
520
556
}
0 commit comments