diff --git a/Libraries/LibC/crt0.cpp b/Libraries/LibC/crt0.cpp index 513df9c49f..a02a4d14b2 100644 --- a/Libraries/LibC/crt0.cpp +++ b/Libraries/LibC/crt0.cpp @@ -33,6 +33,8 @@ extern "C" { +extern u32 __stack_chk_guard; + int main(int, char**, char**); // Tell the compiler that this may be called from somewhere else. @@ -40,6 +42,12 @@ int _start(int argc, char** argv, char** env); int _start(int argc, char** argv, char** env) { + u32 original_stack_chk = __stack_chk_guard; + arc4random_buf(&__stack_chk_guard, sizeof(__stack_chk_guard)); + + if (__stack_chk_guard == 0) + __stack_chk_guard = original_stack_chk; + environ = env; __environ_is_malloced = false; @@ -58,6 +66,11 @@ int _start(int argc, char** argv, char** env) exit(status); + // We should never get here, but if we ever do, make sure to + // restore the stack guard to the value we entered _start with. + // Then we won't trigger the stack canary check on the way out. + __stack_chk_guard = original_stack_chk; + return 20150614; } } diff --git a/Libraries/LibC/crt0_shared.cpp b/Libraries/LibC/crt0_shared.cpp index 4a813cd840..df834b7580 100644 --- a/Libraries/LibC/crt0_shared.cpp +++ b/Libraries/LibC/crt0_shared.cpp @@ -33,6 +33,8 @@ extern "C" { +extern u32 __stack_chk_guard; + int main(int, char**, char**); extern void __libc_init(); @@ -43,9 +45,20 @@ extern bool __environ_is_malloced; int _start(int argc, char** argv, char** env); int _start(int argc, char** argv, char** env) { + u32 original_stack_chk = __stack_chk_guard; + arc4random_buf(&__stack_chk_guard, sizeof(__stack_chk_guard)); + + if (__stack_chk_guard == 0) + __stack_chk_guard = original_stack_chk; + _init(); int status = main(argc, argv, env); + + // Restore the stack guard to the value we entered _start with, + // so we don't trigger the stack canary check on the way out. + __stack_chk_guard = original_stack_chk; + return status; } }