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 */
