6

This is probably a very basic question. I've read about canaries, and how they work in theory. You have a global variable that you set to a random number in the prolog of a function, do your function, and then verify its authenticity in the epilog.

void foobar(int a, int b)
{
   prolog();
   int c = a;
   int d = b;
   char *buffer[40];
   strcpy(stupidcopy);
   epilog();
}

What I don't understand is, how do I place something on the stack in prolog? Like, if I call prolog, and tell it to save a local variable, it'll be on stack, but when we get out of prolog(), won't it be popped? How can I save the canary on stack? Do I need to modify esp using assembly code to do this?

1
  • 8
    Step 1: Become a compiler Jun 16, 2013 at 8:30

2 Answers 2

8

Usually it's the compiler who generates canaries. Prologue and epilogue aren't function calls, they're the instructions the compiler places at the beginning and end of a function.

Consider a naive compiler which puts variables on the stack in the same order they appear in the code and doesn't use registers. Then your function might become:

// variables on stack
int c;
int d;
char *buffer[40];
int canary;

// prologue
canary = secret;

// normal code
c=a;
d=b;
strcpy(stupidcopy);

// epilogue
if(canary != secret)
    OhNoesABufferOverflow();
return;

You can't write this code yourself since compilers can and do optimize storage on the stack. They can reorder variables, keep them in registers and it could even optimize out canary entirely since no well-behaved code will ever trigger the condition.

0

If you intend to implement it as a security measurement than I suggest not to, why?

  1. First, as @CodesInChaos mentioned in most cases this code will be optimized out.
  2. Perfomance penalty - not all functions should use this protection, it involves more actions and affects performance, when you use in MSVC /GS or in GCC -fstack-protector flag, the compiler will add canaries / security cookie only in functions that are prune to buffer overflow, not all functions.
  3. Safety - in order to truly protect from exploitation of a buffer overflow that corrupts the stack you need to use changing values for canaries, that is another mechanism you will need to implement, but already implemented by the compiler.

If you just want to implement the mechanism or for debug purposes , you can add a volatile buffer with known content at the beginning of a function and check it hasn't change at the end of the function.

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .