Linux GLibC Stack Canary Values

I was recently been asked by a friend how the Linux’s stack canary values work. After performing a quick online research I wasn’t able to find anything useful to give him. So, here is my writing on how GNU C Library stack canary values work. :)WARNING: There is no exploitation information in this post. Just the GLIBC’s stack canary value’s functionality.

Since this post is mostly written for people that are just getting started with system’s internals, I’ll explain everything. The address of the stack pointer at an offset of 0x4 is loaded to ECX, then stack pointer is aligned and the original stack pointer (ECX-4) is pushed into the stack. Then, the well known function prologue takes place. The current base pointer (indicating a new stack frame) is pushed onto the stack and value of the stack pointer is placed in the base pointer. Next, the current value of ECX (containing the original stack pointer’s value) is also pushed on the stack and stack pointer is decremented by 0x14 in order to make sufficient space for the function.

This is the actual stack canary code in the binary. It will obtain the canary’s value from ‘%gs:0x14’ and store it in EAX register. It will then place it on the stack just after the stored, previously constructed stack frame. Then EAX is zeroed out since the canary value has no reason in being left there.

It retrieves the canary value from the stack and stores it in EDX register. Then compares it against ‘%gs:0x14’ which is the actual canary value. If they are equal it will use the ‘je’ (Jump if Equal) instruction to continue with the execution at the 0x804842d address. Otherwise, it will call the __stack_chk_fail() library routine through the PLT.
In the first case, the execution will continue from this point:

The first instruction frees the allocated stack space and the next ones are a common function epilogue procedure. It restores the stored stack and frame pointer by popping them from the stack, updating the stack pointer’s value with the original one stored in ECX and calling ‘ret’ to complete the execution.
This is pretty much what’s going on with the SSP. Now, let’s have a look at the __stack_chk_fail() routine which is implemented in the GNU C Library and you can find it at debug/stack_chk_fail.c like this:

The attribute “noreturn” is used in functions that cannot return such as this one. So, the code is a simple wrapper around __fortify_fail(). This routine is available at debug/fortify_fail.c and here is its code:

Once again it’s a non-return function and it will use the __libc_message() to print a simple message like this:

*** stack smashing detected ***: ./bla terminated

Just for your information, __libc_message() is a POSIX compatible library routine available at sysdeps/posix/libc_fatal.c. I won’t describe it since it’s a common error message printing code.
So, we have talked about what happens after we have an executable application using GCC’s SSP but how about what happens before?
Let’s have a look at the Run-Time Dynamic Linker (RTLD) that is located at etc/rtld.c…

The GCC attribute ‘nocommon’ is used to directly allocate space for that variable and not store it in a ‘common’ storage area. A look at elf/stackguard-macros.h will reveal exactly how this variable is initialized…

As you can see, it uses _dl_setup_stack_chk_guard() to setup the stack canary value. Next, it will initialize the pointer check guard value with an XOR logical operation using either a high precision timer’s current value or the same stack canary value based on the compile time options. Since our main concern is the canary value, we should now have a look at _dl_setup_stack_chk_guard() which is located either at sysdeps/unix/sysv/linux/dl-osinfo.h or sysdeps/generic/dl-osinfo.h depending on the operating system.
The sysdeps/unix/sysv/linux/dl-osinfo.h is UNIX System V release dependent.

If StackGuard’s stack randomization is enabled, it will open ‘/dev/urandom’ and simply read an ‘uintptr_t’ that is stored in ‘ret’ variable. If __read() returned a value that is equal to size of ‘ret’ which means that the reading operation was successful it will simply return that value. If no stack randomization is enabled, it will set ‘p’ to the address of ‘ret’ variable and then change two Bytes of ret’s value to 0xff (255 in decimal) and 0xA (which is the newline character) and return that value. So, the canary value will always be ‘0xff0a0000’ which is the so-called terminator canary value.
The generic implementation which resides at sysdeps/generic/dl-osinfo.h uses just this implementation…

6 Responses

More modern versions of glibc will use the AT_RANDOM bytes provided by the kernel instead of using /dev/urandom or the static canary. Prior to this, many distros would patch the dl_setup_stack_chk_guard() function to extract entropy from the stack and library memory positions to try to get some amount of randomness to avoid the static canary.

GS contains interesting values on its segment. ‘0x14’ for 32bits(or ‘0x28’ for 64bits) is an index defined by “stack_guard” macro, and you have also pointer_guard to mangle some function pointers initialized for handle libc routines.

RE: “Then EAX is zeroed out since the canary value has no reason in being left there.”

True, and it improves security. The clearing of EAX after setting the canary, and the use of XOR to test (and clear) the value in EDX, is most likely done to avoid situations where the canary value could be leaked. This way, the value is only present in a register during the setting and checking of the canary; so a program bug will be less likely to leak the value (which it will then have to get from the TLS or the stack).