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.