*I’m on an Ubuntu x86_64 system, gcc 11.4.0
I have this C program in a file test.c :
int fx( int a, int* b ){
*b = 12;
return a;
}
int main(){
int a = 20;
int b = fx(10,&a);
b+= 5;
}
I compile this file with "gcc test.c -o test". Then I inspect it with "objdump -dw -M suffix test" and I get :
0000000000001149 <fx>:
1149: f3 0f 1e fa endbr64
114d: 55 pushq %rbp
114e: 48 89 e5 movq %rsp,%rbp
1151: 89 7d fc movl %edi,-0x4(%rbp)
1154: 48 89 75 f0 movq %rsi,-0x10(%rbp)
1158: 48 8b 45 f0 movq -0x10(%rbp),%rax
115c: c7 00 0c 00 00 00 movl $0xc,(%rax)
1162: 8b 45 fc movl -0x4(%rbp),%eax
1165: 5d popq %rbp
1166: c3 retq
0000000000001167 <main>:
1167: f3 0f 1e fa endbr64
116b: 55 pushq %rbp
116c: 48 89 e5 movq %rsp,%rbp
116f: 48 83 ec 10 subq $0x10,%rsp
1173: 64 48 8b 04 25 28 00 00 00 movq %fs:0x28,%rax
117c: 48 89 45 f8 movq %rax,-0x8(%rbp)
1180: 31 c0 xorl %eax,%eax
1182: c7 45 f0 14 00 00 00 movl $0x14,-0x10(%rbp)
1189: 48 8d 45 f0 leaq -0x10(%rbp),%rax
118d: 48 89 c6 movq %rax,%rsi
1190: bf 0a 00 00 00 movl $0xa,%edi
1195: e8 af ff ff ff callq 1149 <fx>
119a: 89 45 f4 movl %eax,-0xc(%rbp)
119d: 83 45 f4 05 addl $0x5,-0xc(%rbp)
11a1: b8 00 00 00 00 movl $0x0,%eax
11a6: 48 8b 55 f8 movq -0x8(%rbp),%rdx
11aa: 64 48 2b 14 25 28 00 00 00 subq %fs:0x28,%rdx
11b3: 74 05 je 11ba <main+0x53>
11b5: e8 96 fe ff ff callq 1050 <__stack_chk_fail@plt>
11ba: c9 leaveq
11bb: c3 retq
It looks like the compiler uses stack protector by default as you can tell by looking at the main instructions.
My questions :
-
Is it ok to compile my C program with "gcc test.c -fno-stack-protector -o test"?
-
Is -fno-stack-protector just a safety option that makes us vulnerable to some stack attacks or we should be careful when using this option while compiling because it could break something or create some errors/incompatibilities of some kind ?
-
Why doesn’t my gcc compiler have it on by default whereas in other systems ( macOS x86_64 clang ) I’ve noticed it is on ?
-
What are the scenarios where it makes sense using it versus the ones we should absolutely avoid it ?
2
Answers
-fstack-protector
by default so a distro would need to explicitly configure GCC to disable it by default to change that.I do not see any problem with doing that. For convention, it might be better to place options before operands like so:
The option
-fstack-protector=...
enables extra hardening against stack smashing attacks. If you disable it with-fno-stack-protector
, your code will not benefit from this hardening and may be easier to exploit if it already has an exploitable defect. You can mix and match object files compiled with and without the stack protector as you desire, use of the stack protector causes no incompatibilities. However, only functions defined in translation units that have been compiled with stack protector turned on benefit from this hardening.Canonical has decided to enable this option by default as to make hardening against stack-smashing an “opt out” instead of an ”opt in” as it is on macOS. This improves overall security.
Compiling with stack protector turned on is generally useful and especially so if your code is ran with untrusted input or input coming from network or external storage media. However, there is a minor performance cost. If this is is significant, you may want to turn off the stack protector. Be aware that your application may then be easier to exploit with stack smashing attacks if it has such a defect.