Skip to content

Commit b651f78

Browse files
Auto merge of #148849 - saethlin:windows-stack-protectors, r=<try>
Set -Cpanic=abort in windows-msvc stack protector tests try-job: i686-msvc-1 try-job: i686-msvc-2 try-job: x86_64-msvc-1 try-job: x86_64-msvc-2
2 parents 0b329f8 + 2852654 commit b651f78

File tree

3 files changed

+97
-61
lines changed

3 files changed

+97
-61
lines changed

tests/assembly-llvm/stack-protector/stack-protector-heuristics-effect-windows-32bit.rs

Lines changed: 49 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
//@ [strong] compile-flags: -Z stack-protector=strong
88
//@ [basic] compile-flags: -Z stack-protector=basic
99
//@ [none] compile-flags: -Z stack-protector=none
10-
//@ compile-flags: -C opt-level=2 -Z merge-functions=disabled
10+
//@ compile-flags: -C opt-level=2 -Z merge-functions=disabled -Cpanic=abort
1111

1212
#![crate_type = "lib"]
1313
#![allow(internal_features)]
@@ -16,16 +16,19 @@
1616
// CHECK-LABEL: emptyfn:
1717
#[no_mangle]
1818
pub fn emptyfn() {
19+
// CHECK-DAG: .cv_fpo_endprologue
1920
// all: __security_check_cookie
2021
// strong-NOT: __security_check_cookie
2122
// basic-NOT: __security_check_cookie
2223
// none-NOT: __security_check_cookie
2324
// missing-NOT: __security_check_cookie
25+
// CHECK-DAG: .cv_fpo_endproc
2426
}
2527

2628
// CHECK-LABEL: array_char
2729
#[no_mangle]
2830
pub fn array_char(f: fn(*const char)) {
31+
// CHECK-DAG: .cv_fpo_endprologue
2932
let a = ['c'; 1];
3033
let b = ['d'; 3];
3134
let c = ['e'; 15];
@@ -39,11 +42,14 @@ pub fn array_char(f: fn(*const char)) {
3942
// basic: __security_check_cookie
4043
// none-NOT: __security_check_cookie
4144
// missing-NOT: __security_check_cookie
45+
46+
// CHECK-DAG: .cv_fpo_endproc
4247
}
4348

4449
// CHECK-LABEL: array_u8_1
4550
#[no_mangle]
4651
pub fn array_u8_1(f: fn(*const u8)) {
52+
// CHECK-DAG: .cv_fpo_endprologue
4753
let a = [0u8; 1];
4854
f(&a as *const _);
4955

@@ -55,11 +61,14 @@ pub fn array_u8_1(f: fn(*const u8)) {
5561
// basic-NOT: __security_check_cookie
5662
// none-NOT: __security_check_cookie
5763
// missing-NOT: __security_check_cookie
64+
65+
// CHECK-DAG: .cv_fpo_endproc
5866
}
5967

6068
// CHECK-LABEL: array_u8_small:
6169
#[no_mangle]
6270
pub fn array_u8_small(f: fn(*const u8)) {
71+
// CHECK-DAG: .cv_fpo_endprologue
6372
let a = [0u8; 2];
6473
let b = [0u8; 7];
6574
f(&a as *const _);
@@ -72,11 +81,14 @@ pub fn array_u8_small(f: fn(*const u8)) {
7281
// basic-NOT: __security_check_cookie
7382
// none-NOT: __security_check_cookie
7483
// missing-NOT: __security_check_cookie
84+
85+
// CHECK-DAG: .cv_fpo_endproc
7586
}
7687

7788
// CHECK-LABEL: array_u8_large:
7889
#[no_mangle]
7990
pub fn array_u8_large(f: fn(*const u8)) {
91+
// CHECK-DAG: .cv_fpo_endprologue
8092
let a = [0u8; 9];
8193
f(&a as *const _);
8294

@@ -88,6 +100,8 @@ pub fn array_u8_large(f: fn(*const u8)) {
88100
// basic: __security_check_cookie
89101
// none-NOT: __security_check_cookie
90102
// missing-NOT: __security_check_cookie
103+
104+
// CHECK-DAG: .cv_fpo_endproc
91105
}
92106

93107
#[derive(Copy, Clone)]
@@ -96,6 +110,7 @@ pub struct ByteSizedNewtype(u8);
96110
// CHECK-LABEL: array_bytesizednewtype_9:
97111
#[no_mangle]
98112
pub fn array_bytesizednewtype_9(f: fn(*const ByteSizedNewtype)) {
113+
// CHECK-DAG: .cv_fpo_endprologue
99114
let a = [ByteSizedNewtype(0); 9];
100115
f(&a as *const _);
101116

@@ -107,11 +122,14 @@ pub fn array_bytesizednewtype_9(f: fn(*const ByteSizedNewtype)) {
107122
// basic: __security_check_cookie
108123
// none-NOT: __security_check_cookie
109124
// missing-NOT: __security_check_cookie
125+
126+
// CHECK-DAG: .cv_fpo_endproc
110127
}
111128

112129
// CHECK-LABEL: local_var_addr_used_indirectly
113130
#[no_mangle]
114131
pub fn local_var_addr_used_indirectly(f: fn(bool)) {
132+
// CHECK-DAG: .cv_fpo_endprologue
115133
let a = 5;
116134
let a_addr = &a as *const _ as usize;
117135
f(a_addr & 0x10 == 0);
@@ -134,37 +152,27 @@ pub fn local_var_addr_used_indirectly(f: fn(bool)) {
134152
// basic-NOT: __security_check_cookie
135153
// none-NOT: __security_check_cookie
136154
// missing-NOT: __security_check_cookie
155+
156+
// CHECK-DAG: .cv_fpo_endproc
137157
}
138158

139159
// CHECK-LABEL: local_string_addr_taken
140160
#[no_mangle]
141161
pub fn local_string_addr_taken(f: fn(&String)) {
162+
// CHECK-DAG: .cv_fpo_endprologue
142163
let x = String::new();
143164
f(&x);
144165

145166
// Taking the address of the local variable `x` leads to stack smash
146-
// protection with the `strong` heuristic, but not with the `basic`
147-
// heuristic. It does not matter that the reference is not mut.
148-
//
149-
// An interesting note is that a similar function in C++ *would* be
150-
// protected by the `basic` heuristic, because `std::string` has a char
151-
// array internally as a small object optimization:
152-
// ```
153-
// cat <<EOF | clang++ -O2 -fstack-protector -S -x c++ - -o - | grep stack_chk
154-
// #include <string>
155-
// void f(void (*g)(const std::string&)) {
156-
// std::string x;
157-
// g(x);
158-
// }
159-
// EOF
160-
// ```
161-
//
167+
// protection. It does not matter that the reference is not mut.
162168

163169
// all: __security_check_cookie
164-
// strong-NOT: __security_check_cookie
165-
// basic-NOT: __security_check_cookie
170+
// strong: __security_check_cookie
171+
// basic: __security_check_cookie
166172
// none-NOT: __security_check_cookie
167173
// missing-NOT: __security_check_cookie
174+
175+
// CHECK-DAG: .cv_fpo_endproc
168176
}
169177

170178
pub trait SelfByRef {
@@ -180,6 +188,7 @@ impl SelfByRef for i32 {
180188
// CHECK-LABEL: local_var_addr_taken_used_locally_only
181189
#[no_mangle]
182190
pub fn local_var_addr_taken_used_locally_only(factory: fn() -> i32, sink: fn(i32)) {
191+
// CHECK-DAG: .cv_fpo_endprologue
183192
let x = factory();
184193
let g = x.f();
185194
sink(g);
@@ -194,6 +203,8 @@ pub fn local_var_addr_taken_used_locally_only(factory: fn() -> i32, sink: fn(i32
194203
// basic-NOT: __security_check_cookie
195204
// none-NOT: __security_check_cookie
196205
// missing-NOT: __security_check_cookie
206+
207+
// CHECK-DAG: .cv_fpo_endproc
197208
}
198209

199210
pub struct Gigastruct {
@@ -207,6 +218,7 @@ pub struct Gigastruct {
207218
// CHECK-LABEL: local_large_var_moved
208219
#[no_mangle]
209220
pub fn local_large_var_moved(f: fn(Gigastruct)) {
221+
// CHECK-DAG: .cv_fpo_endprologue
210222
let x = Gigastruct { does: 0, not: 1, have: 2, array: 3, members: 4 };
211223
f(x);
212224

@@ -231,11 +243,14 @@ pub fn local_large_var_moved(f: fn(Gigastruct)) {
231243
// basic: __security_check_cookie
232244
// none-NOT: __security_check_cookie
233245
// missing-NOT: __security_check_cookie
246+
247+
// CHECK-DAG: .cv_fpo_endproc
234248
}
235249

236250
// CHECK-LABEL: local_large_var_cloned
237251
#[no_mangle]
238252
pub fn local_large_var_cloned(f: fn(Gigastruct)) {
253+
// CHECK-DAG: .cv_fpo_endprologue
239254
f(Gigastruct { does: 0, not: 1, have: 2, array: 3, members: 4 });
240255

241256
// A new instance of `Gigastruct` is passed to `f()`, without any apparent
@@ -260,6 +275,8 @@ pub fn local_large_var_cloned(f: fn(Gigastruct)) {
260275
// basic: __security_check_cookie
261276
// none-NOT: __security_check_cookie
262277
// missing-NOT: __security_check_cookie
278+
279+
// CHECK-DAG: .cv_fpo_endproc
263280
}
264281

265282
extern "C" {
@@ -293,49 +310,57 @@ extern "C" {
293310
// CHECK-LABEL: alloca_small_compile_time_constant_arg
294311
#[no_mangle]
295312
pub fn alloca_small_compile_time_constant_arg(f: fn(*mut ())) {
313+
// CHECK-DAG: .cv_fpo_endprologue
296314
f(unsafe { alloca(8) });
297315

298316
// all: __security_check_cookie
299317
// strong-NOT: __security_check_cookie
300318
// basic-NOT: __security_check_cookie
301319
// none-NOT: __security_check_cookie
302320
// missing-NOT: __security_check_cookie
321+
322+
// CHECK-DAG: .cv_fpo_endproc
303323
}
304324

305325
// CHECK-LABEL: alloca_large_compile_time_constant_arg
306326
#[no_mangle]
307327
pub fn alloca_large_compile_time_constant_arg(f: fn(*mut ())) {
328+
// CHECK-DAG: .cv_fpo_endprologue
308329
f(unsafe { alloca(9) });
309330

310331
// all: __security_check_cookie
311332
// strong-NOT: __security_check_cookie
312333
// basic-NOT: __security_check_cookie
313334
// none-NOT: __security_check_cookie
314335
// missing-NOT: __security_check_cookie
336+
337+
// CHECK-DAG: .cv_fpo_endproc
315338
}
316339

317340
// CHECK-LABEL: alloca_dynamic_arg
318341
#[no_mangle]
319342
pub fn alloca_dynamic_arg(f: fn(*mut ()), n: usize) {
343+
// CHECK-DAG: .cv_fpo_endprologue
320344
f(unsafe { alloca(n) });
321345

322346
// all: __security_check_cookie
323347
// strong-NOT: __security_check_cookie
324348
// basic-NOT: __security_check_cookie
325349
// none-NOT: __security_check_cookie
326350
// missing-NOT: __security_check_cookie
351+
352+
// CHECK-DAG: .cv_fpo_endproc
327353
}
328354

329355
// The question then is: in what ways can Rust code generate array-`alloca`
330356
// LLVM instructions? This appears to only be generated by
331357
// rustc_codegen_ssa::traits::Builder::array_alloca() through
332-
// rustc_codegen_ssa::mir::operand::OperandValue::store_unsized(). FWICT
333-
// this is support for the "unsized locals" unstable feature:
334-
// https://doc.rust-lang.org/unstable-book/language-features/unsized-locals.html.
358+
// rustc_codegen_ssa::mir::operand::OperandValue::store_unsized().
335359

336360
// CHECK-LABEL: unsized_fn_param
337361
#[no_mangle]
338362
pub fn unsized_fn_param(s: [u8], l: bool, f: fn([u8])) {
363+
// CHECK-DAG: .cv_fpo_endprologue
339364
let n = if l { 1 } else { 2 };
340365
f(*Box::<[u8]>::from(&s[0..n])); // slice-copy with Box::from
341366

@@ -346,14 +371,11 @@ pub fn unsized_fn_param(s: [u8], l: bool, f: fn([u8])) {
346371
// alloca, and is therefore not protected by the `strong` or `basic`
347372
// heuristics.
348373

349-
// We should have a __security_check_cookie call in `all` and `strong` modes but
350-
// LLVM does not support generating stack protectors in functions with funclet
351-
// based EH personalities.
352-
// https://github.com/llvm/llvm-project/blob/37fd3c96b917096d8a550038f6e61cdf0fc4174f/llvm/lib/CodeGen/StackProtector.cpp#L103C1-L109C4
353374
// all-NOT: __security_check_cookie
354375
// strong-NOT: __security_check_cookie
355-
356376
// basic-NOT: __security_check_cookie
357377
// none-NOT: __security_check_cookie
358378
// missing-NOT: __security_check_cookie
379+
380+
// CHECK-DAG: .cv_fpo_endproc
359381
}

0 commit comments

Comments
 (0)