From fd08c93ef57f71360d74b035214c71d7f7bfc5b8 Mon Sep 17 00:00:00 2001 From: Brian Gianforcaro Date: Sat, 2 Jan 2021 04:27:35 -0800 Subject: [PATCH] LibC: Randomize the stack check cookie value on initialization Previously we had a static stack check cookie value for LibC. Now we randomize the cookie value on LibC initialization, this should help make the stack check more difficult to attack (still possible just a bigger pain). This should also help to catch more bugs. --- Libraries/LibC/crt0.cpp | 13 +++++++++++++ Libraries/LibC/crt0_shared.cpp | 13 +++++++++++++ 2 files changed, 26 insertions(+) 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; } }