diff options
| author | Scott Shawcroft <scott@tannewt.org> | 2018-10-22 17:57:28 -0700 |
|---|---|---|
| committer | Scott Shawcroft <scott@tannewt.org> | 2018-12-04 23:26:04 -0800 |
| commit | 7ad2e6ace34a6d417ec1b84472fa409d5451137b (patch) | |
| tree | 57e75e8a4759607f2efce0e032c13d81b2c38e0e /supervisor | |
| parent | 4b5edd3c03623aa09043d337e69efa4e384cf0a4 (diff) | |
Add stack validity check and raise an error when it happens.
The backtrace cannot be given because it relies on the validity
of the qstr data structures on the heap which may have been
corrupted.
In fact, it still can crash hard when the bytecode itself is
overwritten. To fix, we'd need a way to skip gathering the
backtrace completely.
This also increases the default stack size on M4s so it can
accomodate the stack needed by ASF4s nvm API.
Diffstat (limited to 'supervisor')
| -rwxr-xr-x | supervisor/shared/stack.c | 17 | ||||
| -rwxr-xr-x | supervisor/shared/stack.h | 5 |
2 files changed, 22 insertions, 0 deletions
diff --git a/supervisor/shared/stack.c b/supervisor/shared/stack.c index 6b74742eb..8f4da4ce6 100755 --- a/supervisor/shared/stack.c +++ b/supervisor/shared/stack.c @@ -27,6 +27,7 @@ #include "stack.h" #include "py/mpconfig.h" +#include "py/runtime.h" #include "supervisor/cpu.h" extern uint32_t _estack; @@ -37,6 +38,8 @@ supervisor_allocation* stack_alloc = NULL; #define EXCEPTION_STACK_SIZE 1024 +#define STACK_CANARY_VALUE 0x017829ef + void allocate_stack(void) { mp_uint_t regs[10]; mp_uint_t sp = cpu_get_regs_and_sp(regs); @@ -50,6 +53,19 @@ void allocate_stack(void) { } else { current_stack_size = next_stack_size; } + *stack_alloc->ptr = STACK_CANARY_VALUE; +} + +inline bool stack_ok(void) { + return *stack_alloc->ptr == STACK_CANARY_VALUE; +} + +inline void assert_heap_ok(void) { + if (!stack_ok()) { + asm("nop"); + while(true) {} + mp_raise_RuntimeError(translate("Stack clobbered heap.")); + } } void stack_init(void) { @@ -58,6 +74,7 @@ void stack_init(void) { void stack_resize(void) { if (next_stack_size == current_stack_size) { + *stack_alloc->ptr = STACK_CANARY_VALUE; return; } free_memory(stack_alloc); diff --git a/supervisor/shared/stack.h b/supervisor/shared/stack.h index 3a5c18e7d..8f1e881f2 100755 --- a/supervisor/shared/stack.h +++ b/supervisor/shared/stack.h @@ -37,5 +37,10 @@ void stack_init(void); void stack_resize(void); void set_next_stack_size(uint32_t size); uint32_t get_current_stack_size(void); +bool stack_ok(void); + +// Use this after any calls into a library which may use a lot of stack. This will raise a Python +// exception when the stack has likely overwritten a portio of the heap. +void assert_heap_ok(void); #endif // MICROPY_INCLUDED_SUPERVISOR_STACK_H |
