411 REFERENCE · Wikibooks
Linux Applications Debugging Techniques/Stack corruption
Reference material by Wikibooks contributors. This retains its source identity and is not 411 news reporting.
Stack corruption is rather hard to diagnose. Luckily, gcc 4.x can instrument the code to check for stack corruption:
-fstack-protector Add stack protection to functions that have “alloca” or have a (signed or unsigned) char array with size > 8 (SSP_BUFFER_SIZE)
-fstack-protector-strong To more functions, see below
-fstack-protector-all To ALL functions
gcc will add guard variables and code to check for buffer overflows upon exiting a function. A quick example:
/* Compile with: gcc -ggdb -fstack-protector-all stacktest.c */
#include <stdio.h>
#include <string.h>
void bar(char* str)
{
char buf[4];
strcpy(buf, str);
}
void foo()
{
printf("It survived!");
}
int main(void)
{
bar("Longer than 4.");
foo();
return 0;
}
When run, the program will dump core:
$ ./a.out
*** stack smashing detected ***: ./a.out terminated
Aborted (core dumped)
Core was generated by `./a.out'.
Program terminated with signal 6, Aborted.
#0 0x0000003684030265 in raise () from /lib64/libc.so.6
(gdb) bt full
#0 0x0000003684030265 in raise () from /lib64/libc.so.6
No symbol table info available.
#1 0x0000003684031d10 in abort () from /lib64/libc.so.6
No symbol table info available.
#2 0x000000368406a84b in __libc_message () from /lib64/libc.so.6
No symbol table info available.
#3 0x00000036840e8ebf in __stack_chk_fail () from /lib64/libc.so.6
No symbol table info available.
#4 0x0000000000400584 in bar (str=0x400715 "Longer than 4.") at stacktest.c:10
buf = "Long"
#5 0x00000000004005e3 in main () at stacktest.c:19
No locals.
-fstack-protector-strong
Added by google to gcc.
Benefit - gain big performance while sacrificing little security (for scenarios using -fstack-protector-all)
Background - some times stack-protector is too-simple while stack-protector-all over-kills, for example, to build one of our core systems, we forcibly add
"-fstack-protector-all" to all compile commands, which brings big performance penalty (due to extra stack guard/check insns on function prologue and epilogue)
on both atom and arm. To use "-fstack-protector" is just regarded as not secure enough (only "protects" <2% functions) by the system secure team. "-fstack-protector-strong"
hits the balance between "-fstack-protector" and "-fstack-protector-all".
Adds the check to a function:
if any of its local variable’s address is taken, as part of the RHS of an assignment
or if any of its local variable’s address is taken as part of a function argument.
or if it has an array, regardless of array type or length
or if it has a struct/union which contains an array, regardless of array type or length.
or if function has register local variables
See http://gcc.gnu.org/ml/gcc-patches/2012-06/msg00974.html
Further reading
http://www.drdobbs.com/cpp/240001832
New -strong stack protector option for gcc
Starting with gcc 4.9 and later, you can use the ubsan sanitizer for bounds checking.