I am trying to implement stack canaries manually and without the standard library. Therefore I have created a simple PoC with the help of this guide from the OSDev wiki. The article suggests that a simple implementation must provide the __stack_chk_guard
variable and the __stack_chk_fail()
handler.
However, when I compile using GCC and provide the -fstack-protector-all
flag, the executable does not contain any stack canary check at all. What am I missing to get GCC to include the stack canary logic?
gcc -Wall -nostdlib -nodefaultlibs -fstack-protector-all -g -m64 -o poc main.c customlib.h
main.c
#include "customlib.h"
#define STACK_CHK_GUARD (0xDEADBEEFFFFFFFF & ~0xFF)
uintptr_t __stack_chk_guard = STACK_CHK_GUARD;
__attribute__((noreturn)) void __stack_chk_fail()
{
__exit(123);
while(1);
}
int main()
{
__attribute__((unused)) char buffer[16];
for (size_t index = 0; index < 32; index++)
{
buffer[index] = 'A';
}
return 0;
}
customlib.h
This code is mostly irrelevant and is just necessary so that the program can be compiled and linked correctly.
typedef unsigned long int size_t;
typedef unsigned long int uintptr_t;
size_t __syscall(size_t arg1, size_t arg2, size_t arg3, size_t arg4, size_t arg5, size_t arg6)
{
asm("int $0x80\n"
: "=a"(arg1)
: "a"(arg1), "b"(arg2), "c"(arg3), "d"(arg4), "S"(arg5), "D"(arg6));
return arg1;
}
void _exit(int exit_code)
{
__syscall(1, exit_code, 0, 0, 0, 0);
while(1);
}
extern int main();
void _start()
{
main();
_exit(0);
}
GCC version 10.2.0, Linux 5.10.36-2-MANJARO GNU/Linux
It looks like the Arch gcc package (which the Manjaro package is based on) is turning off -fstack-protector
when building without the standard library (Done for Arch bug 64270).
This behavior is apparently also present in Gentoo.
I haven't tried this, but I believe you should be able to dump the GCC specs using gcc -dumpspecs
into a file, keeping only the section *cc1_options
, removing %{nostdlib|nodefaultlibs|ffreestanding:-fno-stack-protector}
from it, and passing it to gcc with gcc -specs=your_spec_file
.
Alternately, you can rebuild the gcc package with this patch removed.