-
Notifications
You must be signed in to change notification settings - Fork 15.2k
Description
When compiled with SSP Strong (-fstack-protector-strong), the following C test-case produces different code depending on whether Exception Handling is enabled:
extern void my_exit(void) __attribute__((__noreturn__));
extern void bar(int *);
void foo(void) {
int buf[10];
bar(buf);
my_exit();
}
Here is what happens with a modern x86_64 Clang (tested with main 3755ea9):
$ clang -S -O2 -fstack-protector-strong -o test.O2.s test.c
$ clang -S -O2 -fstack-protector-strong -fexceptions -o test.O2.eh.s test.c
$ diff test.O2.s test.O2.eh.s
9,10c9,12
< subq $40, %rsp
< .cfi_def_cfa_offset 48
---
> subq $56, %rsp
> .cfi_def_cfa_offset 64
> movq %fs:40, %rax
> movq %rax, 48(%rsp)
12a15,18
> movq %fs:40, %rax
> cmpq 48(%rsp), %rax
> jne .LBB0_2
> # %bb.1: # %SP_return
13a20,21
> .LBB0_2: # %CallStackCheckFailBlk
> callq __stack_chk_fail@PLT
20a29
> .addrsig_sym __stack_chk_fail
$
Enabling Exception Handling in C compilations shouldn't change the generated code. More directly, the problem here is that in compiling a noreturn C function with -fexceptions, we are enabling the generation of the SSP canary, due to the concern of a security hole in exception-handling-unwinding, described in:
https://bugs.chromium.org/p/llvm/issues/detail?id=30
But there isn't any unwinding in a C program, regardless of whether -fexceptions was specified. So that SSP support isn't needed. And more generally, turning on -fexceptions should be a no-op in compiling C code. Is this a wider (and latent) Clang issue for C compilations, in that we normally tag C functions as nounwind, and turning on -fexceptions shouldn't change that?
This is a regression in llvm16 (initially related to d656ae2), and as noted above it still exists in main. (A related aspect was partially addressed in llvm17 fc4494d. And that was cherry-picked to the llvm16 release (bf80902).)