15.3.3 Customizing the Stack Canary Value
The Stack Smashing Protector implementation relies on a secret value that is placed on a protected function's call stack. This value, called the "canary", is determined at compile time. Your application code can (and should) define an application-specific value. The value must be kept secret from any potential attacker.
unsigned long __stack_chk_guard;
void __attribute__((no_stack_protector)) _on_bootstrap(void) {
__stack_chk_guard = 0xDEADBEEF; // the canary value
}
void __attribute__((noreturn)) __stack_chk_fail (void) {
// XC32 default weak implementation
while(1) {
// Replace this code with application-specific code
__builtin_software_breakpoint();
}
}
void foo (char* ptr) {
int retval;
char buffer[10]; // buffer located on the stack
int i=0;
// A buffer overrun here will cause a stack smash. The SSP feature helps you to
// identify and catch vulnerabilities in your application code but does not prevent them.
while (*ptr != 0) {
buffer[i++] = ptr[i];
}
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)
continue;
}
Execution of the example code should stop at the software breakpoint in the
__stack_chk_fail() function.
The _on_bootstrap function name is used, since this function runs after
the C library has been initialized via __libc_init_array. If
the _on_reset function name is used instead, note that this
function will work correctly provided you are using the default startup code obtained
from a DFP. If you are providing your own startup code, this code will need to call the
function that sets up the canary value manually and at the correct time.
The no_stack_protector attribute has been used with the function that
changes the canary value, even though this is not strictly necessary. Doing so will
allow the code to execute correctly in cases where the
-fstack-protector option has been specified.
