This is an automated email from the ASF dual-hosted git repository.

acassis pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/nuttx.git


The following commit(s) were added to refs/heads/master by this push:
     new 981ef0f1a78 arch/arm: set PSPLIM to top of TLS region to protect it 
from overflow
981ef0f1a78 is described below

commit 981ef0f1a782a110ed085722c21a1f1fac1e1758
Author: Junbo Zheng <[email protected]>
AuthorDate: Mon Jul 20 16:52:46 2026 +0800

    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 <[email protected]>
---
 arch/arm/src/armv8-m/arm_initialstate.c | 9 +++++++--
 1 file changed, 7 insertions(+), 2 deletions(-)

diff --git a/arch/arm/src/armv8-m/arm_initialstate.c 
b/arch/arm/src/armv8-m/arm_initialstate.c
index 162335b9d66..962050fa2c0 100644
--- a/arch/arm/src/armv8-m/arm_initialstate.c
+++ b/arch/arm/src/armv8-m/arm_initialstate.c
@@ -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) */

Reply via email to