diff --git a/kernel/include/kernel_internal.h b/kernel/include/kernel_internal.h index 4f9b44a7041..94f76feba26 100644 --- a/kernel/include/kernel_internal.h +++ b/kernel/include/kernel_internal.h @@ -206,6 +206,12 @@ extern void smp_timer_init(void); extern void z_newlib_get_heap_bounds(void **base, size_t *size); #endif +extern u32_t z_early_boot_rand32_get(void); + +#if CONFIG_STACK_POINTER_RANDOM +extern int z_stack_adjust_initialized; +#endif + #ifdef __cplusplus } #endif diff --git a/kernel/init.c b/kernel/init.c index a66beeb1646..8dd8aff4003 100644 --- a/kernel/init.c +++ b/kernel/init.c @@ -29,6 +29,7 @@ #include #include #include +#include /* kernel build timestamp items */ #define BUILD_TIMESTAMP "BUILD: " __DATE__ " " __TIME__ @@ -206,6 +207,9 @@ static void bg_thread_main(void *unused1, void *unused2, void *unused3) ARG_UNUSED(unused3); _sys_device_do_config_level(_SYS_INIT_LEVEL_POST_KERNEL); +#if CONFIG_STACK_POINTER_RANDOM + z_stack_adjust_initialized = 1; +#endif if (boot_delay > 0) { printk("***** delaying boot " STRINGIFY(CONFIG_BOOT_DELAY) "ms (per build configuration) *****\n"); @@ -374,26 +378,20 @@ static void switch_to_main_thread(void) #endif } -#ifdef CONFIG_STACK_CANARIES -#include - -extern uintptr_t __stack_chk_guard; - -static inline void _initialize_stack_canaries(void) +u32_t z_early_boot_rand32_get(void) { #ifdef CONFIG_ENTROPY_HAS_DRIVER struct device *entropy = device_get_binding(CONFIG_ENTROPY_NAME); int rc; + u32_t retval; if (entropy == NULL) { goto sys_rand32_fallback; } - rc = entropy_get_entropy(entropy, - (u8_t *)&__stack_chk_guard, - sizeof(__stack_chk_guard)); + rc = entropy_get_entropy(entropy, (u8_t *)&retval, sizeof(retval)); if (rc == 0) { - return; + return retval; } /* FIXME: rc could be -EAGAIN here, for cases where the entropy @@ -410,8 +408,11 @@ sys_rand32_fallback: * devices are available should be built, this is only a fallback for * those devices without a HWRNG entropy driver. */ - __stack_chk_guard = (uintptr_t)sys_rand32_get(); + return sys_rand32_get(); } + +#ifdef CONFIG_STACK_CANARIES +extern uintptr_t __stack_chk_guard; #endif /* CONFIG_STACK_CANARIES */ /** @@ -455,7 +456,7 @@ FUNC_NORETURN void _Cstart(void) _sys_device_do_config_level(_SYS_INIT_LEVEL_PRE_KERNEL_2); #ifdef CONFIG_STACK_CANARIES - _initialize_stack_canaries(); + __stack_chk_guard = z_early_boot_rand32_get(); #endif prepare_multithreading(dummy_thread); diff --git a/kernel/thread.c b/kernel/thread.c index 827a984fa51..514f2b0ab53 100644 --- a/kernel/thread.c +++ b/kernel/thread.c @@ -26,6 +26,7 @@ #include #include #include +#include extern struct _static_thread_data _static_thread_data_list_start[]; extern struct _static_thread_data _static_thread_data_list_end[]; @@ -254,15 +255,25 @@ static inline size_t adjust_stack_size(size_t stack_size) return stack_size; } #else +int z_stack_adjust_initialized; + static inline size_t adjust_stack_size(size_t stack_size) { + size_t random_val; + + if (!z_stack_adjust_initialized) { + random_val = z_early_boot_rand32_get(); + } else { + random_val = sys_rand32_get(); + } + /* Don't need to worry about alignment of the size here, _new_thread() * is required to do it * * FIXME: Not the best way to get a random number in a range. * See #6493 */ - const size_t fuzz = sys_rand32_get() % CONFIG_STACK_POINTER_RANDOM; + const size_t fuzz = random_val % CONFIG_STACK_POINTER_RANDOM; if (unlikely(fuzz * 2 > stack_size)) { return stack_size; @@ -270,7 +281,6 @@ static inline size_t adjust_stack_size(size_t stack_size) return stack_size - fuzz; } - #if defined(CONFIG_STACK_GROWS_UP) /* This is so rare not bothering for now */ #error "Stack pointer randomization not implemented for upward growing stacks"