diff --git a/include/nuttx/tls.h b/include/nuttx/tls.h index 4646ba5cef1..4159035d000 100644 --- a/include/nuttx/tls.h +++ b/include/nuttx/tls.h @@ -199,7 +199,7 @@ struct tls_cleanup_s struct tls_info_s { - FAR struct task_info_s * tl_task; + FAR struct task_info_s *tl_task; #if defined(CONFIG_TLS_NELEM) && CONFIG_TLS_NELEM > 0 uintptr_t tl_elem[CONFIG_TLS_NELEM]; /* TLS elements */ @@ -224,6 +224,7 @@ struct tls_info_s uint16_t tl_size; /* Actual size with alignments */ int tl_errno; /* Per-thread error number */ pid_t tl_tid; /* Thread ID */ + FAR char **tl_argv; /* Arguments first string */ }; /**************************************************************************** diff --git a/sched/sched/sched_get_tls.c b/sched/sched/sched_get_tls.c index db178095d72..4fb5ce71428 100644 --- a/sched/sched/sched_get_tls.c +++ b/sched/sched/sched_get_tls.c @@ -75,6 +75,5 @@ FAR char **nxsched_get_stackargs(FAR struct tcb_s *tcb) { /* The args data follows the TLS data */ - return (FAR char**)((FAR char *)tcb->stack_alloc_ptr + - nxsched_get_tls(tcb)->tl_size); + return nxsched_get_tls(tcb)->tl_argv; } diff --git a/sched/task/task_argvstr.c b/sched/task/task_argvstr.c index a835835ef26..d4854b78298 100644 --- a/sched/task/task_argvstr.c +++ b/sched/task/task_argvstr.c @@ -89,11 +89,14 @@ size_t nxtask_argvstr(FAR struct tcb_s *tcb, FAR char *args, size_t size) else #endif { - FAR char **argv = nxsched_get_stackargs(tcb) + 1; + FAR char **argv = nxsched_get_stackargs(tcb); - while (*argv != NULL && n < size) + if (argv++) { - n += snprintf(args + n, size - n, " %s", *argv++); + while (*argv != NULL && n < size) + { + n += snprintf(args + n, size - n, " %s", *argv++); + } } } diff --git a/sched/task/task_setup.c b/sched/task/task_setup.c index c226bdbc27d..6748392401d 100644 --- a/sched/task/task_setup.c +++ b/sched/task/task_setup.c @@ -630,6 +630,9 @@ int nxtask_setup_stackargs(FAR struct tcb_s *tcb, stackargv[argc + 1] = NULL; + /* Initialize argv last to avoid accessing the partial initialized fields */ + + nxsched_get_tls(tcb)->tl_argv = stackargv; return OK; } diff --git a/sched/tls/tls_dupinfo.c b/sched/tls/tls_dupinfo.c index de7a4022c09..0987e9d6170 100644 --- a/sched/tls/tls_dupinfo.c +++ b/sched/tls/tls_dupinfo.c @@ -70,5 +70,12 @@ int tls_dup_info(FAR struct tcb_s *dst, FAR struct tcb_s *src) /* Attach per-task info in group to TLS */ info->tl_task = dst->group->tg_info; + + /* Initialize the starting address of argv to NULL to prevent + * it from being misused. + */ + + info->tl_argv = NULL; + return OK; } diff --git a/sched/tls/tls_initinfo.c b/sched/tls/tls_initinfo.c index bf7227fd1a5..c38704a19cf 100644 --- a/sched/tls/tls_initinfo.c +++ b/sched/tls/tls_initinfo.c @@ -78,5 +78,11 @@ int tls_init_info(FAR struct tcb_s *tcb) info->tl_tid = tcb->pid; + /* Initialize the starting address of argv to NULL to prevent + * it from being misused. + */ + + info->tl_argv = NULL; + return OK; }