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

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

commit 73fe4cbb3088d55a0d6f072f1e6e70771bfeaa37
Author: Marco Casaroli <[email protected]>
AuthorDate: Tue Oct 20 21:00:15 2026 +0200

    sched, libc: Fail with EINVAL for a stack larger than the TLS limit.
    
    With CONFIG_TLS_ALIGNED, a stack cannot be larger than its alignment,
    2^CONFIG_TLS_LOG2_MAXSTACK.  A larger request reached up_create_stack()
    or up_use_stack(), which stopped on DEBUGASSERT(stack_size <=
    TLS_MAXSTACK) or, without assertions, used a smaller stack than the
    caller asked for.
    
    pthread_attr_setstacksize() and pthread_attr_setstack() now return
    EINVAL for such a size, as POSIX allows for a size above the system
    limit.  pthread_create() and nxtask_init() (task_create(), posix_spawn()
    and exec()) also check the size, so attributes that are set directly
    fail with EINVAL too.
    
    Assisted-by: Claude Code:claude-opus-5-5
    Signed-off-by: Marco Casaroli <[email protected]>
---
 libs/libc/pthread/pthread_attr_setstack.c     | 10 ++++++++++
 libs/libc/pthread/pthread_attr_setstacksize.c | 10 ++++++++++
 libs/libc/tls/Kconfig                         |  3 ++-
 sched/pthread/pthread_create.c                | 10 ++++++++++
 sched/task/task_init.c                        | 10 ++++++++++
 5 files changed, 42 insertions(+), 1 deletion(-)

diff --git a/libs/libc/pthread/pthread_attr_setstack.c 
b/libs/libc/pthread/pthread_attr_setstack.c
index dff7269c80a..f987e8f1efe 100644
--- a/libs/libc/pthread/pthread_attr_setstack.c
+++ b/libs/libc/pthread/pthread_attr_setstack.c
@@ -24,9 +24,13 @@
  * Included Files
  ****************************************************************************/
 
+#include <nuttx/config.h>
+
 #include <pthread.h>
 #include <errno.h>
 
+#include <nuttx/tls.h>
+
 /****************************************************************************
  * Public Functions
  ****************************************************************************/
@@ -59,6 +63,12 @@ int pthread_attr_setstack(FAR pthread_attr_t *attr,
     {
       ret = EINVAL;
     }
+#ifdef CONFIG_TLS_ALIGNED
+  else if (stacksize > TLS_MAXSTACK)
+    {
+      ret = EINVAL;
+    }
+#endif
   else
     {
       attr->stackaddr = stackaddr;
diff --git a/libs/libc/pthread/pthread_attr_setstacksize.c 
b/libs/libc/pthread/pthread_attr_setstacksize.c
index 689ee7a4023..5b2fed3a69b 100644
--- a/libs/libc/pthread/pthread_attr_setstacksize.c
+++ b/libs/libc/pthread/pthread_attr_setstacksize.c
@@ -24,9 +24,13 @@
  * Included Files
  ****************************************************************************/
 
+#include <nuttx/config.h>
+
 #include <pthread.h>
 #include <errno.h>
 
+#include <nuttx/tls.h>
+
 /****************************************************************************
  * Public Functions
  ****************************************************************************/
@@ -57,6 +61,12 @@ int pthread_attr_setstacksize(FAR pthread_attr_t *attr, 
size_t stacksize)
     {
       ret = EINVAL;
     }
+#ifdef CONFIG_TLS_ALIGNED
+  else if (stacksize > TLS_MAXSTACK)
+    {
+      ret = EINVAL;
+    }
+#endif
   else
     {
       attr->stacksize = stacksize;
diff --git a/libs/libc/tls/Kconfig b/libs/libc/tls/Kconfig
index 69b8866af1b..7e5ce6a3cda 100644
--- a/libs/libc/tls/Kconfig
+++ b/libs/libc/tls/Kconfig
@@ -40,7 +40,8 @@ config TLS_LOG2_MAXSTACK
                except that (1) a very large value can cause you to run out of
                alignable memory (and fail memory allocations), and (2) smaller
                values will limit the maximum size of the stack (hence the 
naming
-               of this configuration value).
+               of this configuration value).  A request for a larger stack 
fails
+               with EINVAL.
 
 config TLS_NELEM
        int "Number of TLS elements"
diff --git a/sched/pthread/pthread_create.c b/sched/pthread/pthread_create.c
index 8b245239dd8..eaaa165ef1e 100644
--- a/sched/pthread/pthread_create.c
+++ b/sched/pthread/pthread_create.c
@@ -214,6 +214,16 @@ int nx_pthread_create(pthread_trampoline_t trampoline, FAR 
pthread_t *thread,
       attr = &default_attr;
     }
 
+#ifdef CONFIG_TLS_ALIGNED
+  /* The TLS alignment limits the size of the stack */
+
+  if (attr->stacksize + (attr->stackaddr ? 0 : attr->guardsize) >
+      TLS_MAXSTACK)
+    {
+      return EINVAL;
+    }
+#endif
+
   /* Allocate a TCB for the new task. */
 
   ptcb = kmm_zalloc(sizeof(struct tcb_s) + sizeof(struct pthread_entry_s));
diff --git a/sched/task/task_init.c b/sched/task/task_init.c
index 5c24e04aa54..1b5730a0dc1 100644
--- a/sched/task/task_init.c
+++ b/sched/task/task_init.c
@@ -102,6 +102,16 @@ int nxtask_init(FAR struct tcb_s *tcb, const char *name, 
int priority,
   DEBUGASSERT(tcb && ttype != TCB_FLAG_TTYPE_PTHREAD);
 #endif
 
+#ifdef CONFIG_TLS_ALIGNED
+  /* The TLS alignment limits the size of the stack */
+
+  if (stack_size > TLS_MAXSTACK)
+    {
+      sched_trace_end();
+      return -EINVAL;
+    }
+#endif
+
 #ifdef CONFIG_ARCH_ADDRENV
   /* Kernel threads do not own any address environment */
 

Reply via email to