Check stack canary for noreturn function to catch stack corruption before calling noreturn function. For C++, check stack canary when throwing exception or resuming stack unwind to avoid corrupted stack.
gcc/ PR middle-end/58245 * calls.cc (expand_call): Check stack canary for noreturn function. gcc/testsuite/ PR middle-end/58245 * c-c++-common/pr58245-1.c: New test. * g++.dg/pr58245-1.C: Likewise. * g++.dg/fstack-protector-strong.C: Adjusted. --- gcc/calls.cc | 7 ++++++- gcc/testsuite/c-c++-common/pr58245-1.c | 12 ++++++++++++ gcc/testsuite/g++.dg/fstack-protector-strong.C | 2 +- gcc/testsuite/g++.dg/pr58245-1.C | 10 ++++++++++ 4 files changed, 29 insertions(+), 2 deletions(-) create mode 100644 gcc/testsuite/c-c++-common/pr58245-1.c create mode 100644 gcc/testsuite/g++.dg/pr58245-1.C diff --git a/gcc/calls.cc b/gcc/calls.cc index bc96aff38f0..7816c2c8d99 100644 --- a/gcc/calls.cc +++ b/gcc/calls.cc @@ -3154,7 +3154,12 @@ expand_call (tree exp, rtx target, int ignore) if (pass && (flags & ECF_MALLOC)) start_sequence (); - if (pass == 0 + /* Check the canary value for sibcall or function which doesn't + return. */ + if ((pass == 0 + || ((flags & ECF_NORETURN) != 0 + && (fndecl + != get_callee_fndecl (targetm.stack_protect_fail ())))) && crtl->stack_protect_guard && targetm.stack_protect_runtime_enabled_p ()) stack_protect_epilogue (); diff --git a/gcc/testsuite/c-c++-common/pr58245-1.c b/gcc/testsuite/c-c++-common/pr58245-1.c new file mode 100644 index 00000000000..945acc53004 --- /dev/null +++ b/gcc/testsuite/c-c++-common/pr58245-1.c @@ -0,0 +1,12 @@ +/* { dg-do compile { target i?86-*-* x86_64-*-* rs6000-*-* s390x-*-* } } */ +/* { dg-options "-O2 -fstack-protector-all" } */ + +extern void foo (void) __attribute__ ((noreturn)); + +void +bar (void) +{ + foo (); +} + +/* { dg-final { scan-assembler-times "stack_chk_fail" 1 } } */ diff --git a/gcc/testsuite/g++.dg/fstack-protector-strong.C b/gcc/testsuite/g++.dg/fstack-protector-strong.C index ae6d2fdb8df..034af2ce9ab 100644 --- a/gcc/testsuite/g++.dg/fstack-protector-strong.C +++ b/gcc/testsuite/g++.dg/fstack-protector-strong.C @@ -85,4 +85,4 @@ int foo7 (B *p) return p->return_slot ().a1; } -/* { dg-final { scan-assembler-times "stack_chk_fail" 7 } } */ +/* { dg-final { scan-assembler-times "stack_chk_fail" 8 } } */ diff --git a/gcc/testsuite/g++.dg/pr58245-1.C b/gcc/testsuite/g++.dg/pr58245-1.C new file mode 100644 index 00000000000..1439bc62e71 --- /dev/null +++ b/gcc/testsuite/g++.dg/pr58245-1.C @@ -0,0 +1,10 @@ +/* { dg-do compile { target i?86-*-* x86_64-*-* rs6000-*-* s390x-*-* } } */ +/* { dg-options "-O2 -fstack-protector-all" } */ + +void +bar (void) +{ + throw 1; +} + +/* { dg-final { scan-assembler-times "stack_chk_fail" 1 } } */ -- 2.36.1