15.3.4 Stack Smash Protector at Work
Let’s see an example id when Stack Smash Protector demonstrates its usefulness:
extern unsigned long __stack_chk_guard;
void __attribute__((constructor, optimize("-fno-stack-protector")))
my_stack_guard_setup(void)
{
__stack_chk_guard = 0xDEADBEEF; // the new value for the canary
}
void __attribute__((noreturn)) __stack_chk_fail(void)
{
// handle the failure in a way that is appropriate for your application
while(1)
{
// A software breakpoint is not likely to be an appropriate response to an attack!
__builtin_software_breakpoint();
}
}
void foo (char* ptr)
{
int retval;
char buffer[10]; // buffer located on the stack
char *dest = buffer;
// A buffer overrun here will cause a stack smash
// The SSP feature helps you to identify & catch vulnerabilities in your application code.
// It does not prevent them.
while (*ptr != 0)
{
*dest++ = *ptr++;
}
return;
}
int main (void)
{
// In a real application, this data may come from an external source,
// making the application vulnerable to an attack.
char string[] = "hello world!";
foo(string);
while(1);
}
The example is built successfully with –fstack-protector
and debugged on
a target device, execution should stop at the software breakpoint in the
__stack_chk_fail()
function.