mirror of
https://github.com/apache/nuttx.git
synced 2026-08-10 15:05:07 +00:00
arch/arm: set PSPLIM to top of TLS region to protect it from overflow
A crash was observed when running ps: a BusFault in nxtask_argvstr dereferencing tl_argv, because a thread's stack overflow had silently corrupted the TLS region where tl_argv resides. On ARMv8-M with CONFIG_ARMV8M_STACKCHECK_HARDWARE, PSPLIM was set to stack_alloc_ptr -- the bottom of the allocation where TLS begins. The stack grows downward and TLS occupies [stack_alloc_ptr, stack_alloc_ptr + tls_info_size()), so an overflow crossed into TLS and clobbered tl_argv before SP reached the limit, going undetected until code that read the corrupted TLS data (such as ps) hit the bad pointer. Set the limit to stack_alloc_ptr + tls_info_size() -- the top of the TLS region and the usable stack base -- so an overflow faults at the TLS boundary, before any TLS byte is touched. Include <tls/tls.h> for the tls_info_size() macro, which is the value sched reserves for the TLS region via up_stack_frame(). Signed-off-by: Junbo Zheng <zhengjunbo1@xiaomi.com>
This commit is contained in:
parent
69d7833fba
commit
311069da9c
1 changed files with 7 additions and 2 deletions
|
|
@ -31,6 +31,7 @@
|
|||
#include <string.h>
|
||||
|
||||
#include <nuttx/arch.h>
|
||||
#include <tls/tls.h>
|
||||
#include <arch/armv8-m/nvicpri.h>
|
||||
|
||||
#include "arm_internal.h"
|
||||
|
|
@ -106,9 +107,13 @@ void up_initial_state(struct tcb_s *tcb)
|
|||
#endif
|
||||
|
||||
#ifdef CONFIG_ARMV8M_STACKCHECK_HARDWARE
|
||||
/* Save the stack limit value, will be used in context switch. */
|
||||
/* Save the stack limit (restored on context switch) at the top of the
|
||||
* TLS region. The stack grows downward and TLS occupies the bottom of
|
||||
* the allocation, so an overflow faults here before it clobbers TLS
|
||||
* data instead of silently corrupting it first.
|
||||
*/
|
||||
|
||||
xcp->regs[REG_SPLIM] = (uint32_t)tcb->stack_alloc_ptr;
|
||||
xcp->regs[REG_SPLIM] = (uint32_t)tcb->stack_alloc_ptr + tls_info_size();
|
||||
#endif
|
||||
|
||||
/* Save the task entry point (stripping off the thumb bit) */
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue