Browse Source

kernel: handle early entropy issues

We generalize querying the entropy driver directly with
a new internal API, which is now used by CONFIG_STACK_RANDOM
and stack canary initialization.

Signed-off-by: Andrew Boie <andrew.p.boie@intel.com>
pull/7844/head
Andrew Boie 7 years ago committed by Andrew Boie
parent
commit
538754cb28
  1. 6
      kernel/include/kernel_internal.h
  2. 25
      kernel/init.c
  3. 14
      kernel/thread.c

6
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); extern void z_newlib_get_heap_bounds(void **base, size_t *size);
#endif #endif
extern u32_t z_early_boot_rand32_get(void);
#if CONFIG_STACK_POINTER_RANDOM
extern int z_stack_adjust_initialized;
#endif
#ifdef __cplusplus #ifdef __cplusplus
} }
#endif #endif

25
kernel/init.c

@ -29,6 +29,7 @@
#include <misc/dlist.h> #include <misc/dlist.h>
#include <kernel_internal.h> #include <kernel_internal.h>
#include <kswap.h> #include <kswap.h>
#include <entropy.h>
/* kernel build timestamp items */ /* kernel build timestamp items */
#define BUILD_TIMESTAMP "BUILD: " __DATE__ " " __TIME__ #define BUILD_TIMESTAMP "BUILD: " __DATE__ " " __TIME__
@ -206,6 +207,9 @@ static void bg_thread_main(void *unused1, void *unused2, void *unused3)
ARG_UNUSED(unused3); ARG_UNUSED(unused3);
_sys_device_do_config_level(_SYS_INIT_LEVEL_POST_KERNEL); _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) { if (boot_delay > 0) {
printk("***** delaying boot " STRINGIFY(CONFIG_BOOT_DELAY) printk("***** delaying boot " STRINGIFY(CONFIG_BOOT_DELAY)
"ms (per build configuration) *****\n"); "ms (per build configuration) *****\n");
@ -374,26 +378,20 @@ static void switch_to_main_thread(void)
#endif #endif
} }
#ifdef CONFIG_STACK_CANARIES u32_t z_early_boot_rand32_get(void)
#include <entropy.h>
extern uintptr_t __stack_chk_guard;
static inline void _initialize_stack_canaries(void)
{ {
#ifdef CONFIG_ENTROPY_HAS_DRIVER #ifdef CONFIG_ENTROPY_HAS_DRIVER
struct device *entropy = device_get_binding(CONFIG_ENTROPY_NAME); struct device *entropy = device_get_binding(CONFIG_ENTROPY_NAME);
int rc; int rc;
u32_t retval;
if (entropy == NULL) { if (entropy == NULL) {
goto sys_rand32_fallback; goto sys_rand32_fallback;
} }
rc = entropy_get_entropy(entropy, rc = entropy_get_entropy(entropy, (u8_t *)&retval, sizeof(retval));
(u8_t *)&__stack_chk_guard,
sizeof(__stack_chk_guard));
if (rc == 0) { if (rc == 0) {
return; return retval;
} }
/* FIXME: rc could be -EAGAIN here, for cases where the entropy /* 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 * devices are available should be built, this is only a fallback for
* those devices without a HWRNG entropy driver. * 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 */ #endif /* CONFIG_STACK_CANARIES */
/** /**
@ -455,7 +456,7 @@ FUNC_NORETURN void _Cstart(void)
_sys_device_do_config_level(_SYS_INIT_LEVEL_PRE_KERNEL_2); _sys_device_do_config_level(_SYS_INIT_LEVEL_PRE_KERNEL_2);
#ifdef CONFIG_STACK_CANARIES #ifdef CONFIG_STACK_CANARIES
_initialize_stack_canaries(); __stack_chk_guard = z_early_boot_rand32_get();
#endif #endif
prepare_multithreading(dummy_thread); prepare_multithreading(dummy_thread);

14
kernel/thread.c

@ -26,6 +26,7 @@
#include <syscall_handler.h> #include <syscall_handler.h>
#include <kernel_internal.h> #include <kernel_internal.h>
#include <kswap.h> #include <kswap.h>
#include <init.h>
extern struct _static_thread_data _static_thread_data_list_start[]; extern struct _static_thread_data _static_thread_data_list_start[];
extern struct _static_thread_data _static_thread_data_list_end[]; 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; return stack_size;
} }
#else #else
int z_stack_adjust_initialized;
static inline size_t adjust_stack_size(size_t stack_size) 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() /* Don't need to worry about alignment of the size here, _new_thread()
* is required to do it * is required to do it
* *
* FIXME: Not the best way to get a random number in a range. * FIXME: Not the best way to get a random number in a range.
* See #6493 * 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)) { if (unlikely(fuzz * 2 > stack_size)) {
return stack_size; return stack_size;
@ -270,7 +281,6 @@ static inline size_t adjust_stack_size(size_t stack_size)
return stack_size - fuzz; return stack_size - fuzz;
} }
#if defined(CONFIG_STACK_GROWS_UP) #if defined(CONFIG_STACK_GROWS_UP)
/* This is so rare not bothering for now */ /* This is so rare not bothering for now */
#error "Stack pointer randomization not implemented for upward growing stacks" #error "Stack pointer randomization not implemented for upward growing stacks"

Loading…
Cancel
Save