From: Keith Packard Date: Tue, 13 Jun 2023 06:13:29 +0000 (-0700) Subject: altos: Add AO_STACK_CANARY to detect stack overflows sometimes X-Git-Tag: 1.9.17~1^2~10 X-Git-Url: https://git.gag.com/?p=fw%2Faltos;a=commitdiff_plain;h=2dd10fcc43369129b1d5067f10365574a12943eb altos: Add AO_STACK_CANARY to detect stack overflows sometimes Checks above and below the current task stack at each switch. Signed-off-by: Keith Packard --- diff --git a/src/kernel/ao_task.c b/src/kernel/ao_task.c index b5045416..048f5e67 100644 --- a/src/kernel/ao_task.c +++ b/src/kernel/ao_task.c @@ -307,6 +307,8 @@ ao_stack_top(struct ao_task *task) #endif } +#define AO_STACK_CANARY_VALUE 0xbaadf00dU + void ao_add_task(struct ao_task * task, void (*task_func)(void), const char *name) { @@ -324,6 +326,10 @@ ao_add_task(struct ao_task * task, void (*task_func)(void), const char *name) task->task_id = task_id; task->name = name; task->wchan = NULL; +#ifdef AO_STACK_CANARY + task->bottom_canary = AO_STACK_CANARY_VALUE; + task->top_canary = AO_STACK_CANARY_VALUE; +#endif /* * Construct a stack frame so that it will 'return' * to the start of the task @@ -341,6 +347,19 @@ ao_add_task(struct ao_task * task, void (*task_func)(void), const char *name) ); } +#ifdef AO_STACK_CANARY +static void +ao_check_stack_canary(void) +{ + if (ao_cur_task->bottom_canary != AO_STACK_CANARY_VALUE) + ao_panic(AO_PANIC_STACK); + if (ao_cur_task->top_canary != AO_STACK_CANARY_VALUE) + ao_panic(AO_PANIC_STACK); +} +#else +#define ao_check_stack_canary() +#endif + uint8_t ao_task_minimize_latency; /* Task switching function. */ @@ -356,6 +375,7 @@ ao_yield(void) ao_cur_task->max_run = run; ++ao_cur_task->yields; #endif + ao_check_stack_canary(); ao_arch_save_regs(); ao_arch_save_stack(); } @@ -398,6 +418,7 @@ ao_yield(void) #if USE_TLS _set_tls(ao_stack_top(ao_cur_task)); #endif + ao_check_stack_canary(); ao_arch_restore_stack(); } diff --git a/src/kernel/ao_task.h b/src/kernel/ao_task.h index 9197e25c..27f47a56 100644 --- a/src/kernel/ao_task.h +++ b/src/kernel/ao_task.h @@ -48,10 +48,16 @@ struct ao_task { struct ao_list queue; struct ao_list alarm_queue; /* Provide both 32-bit and 8-bit stacks */ +#ifdef AO_STACK_CANARY + uint32_t bottom_canary; +#endif union { uint32_t stack32[AO_STACK_SIZE>>2]; uint8_t stack8[AO_STACK_SIZE]; } AO_STACK_ALIGNMENT; +#ifdef AO_STACK_CANARY + uint32_t top_canary; +#endif #if HAS_SAMPLE_PROFILE uint32_t ticks; uint32_t yields;