From 92bbe4f6ac92b5bc8db3d2182d832e1c2dd2b505 Mon Sep 17 00:00:00 2001 From: hujun5 Date: Fri, 18 Apr 2025 14:27:23 +0800 Subject: [PATCH] sched/tls: fix uninitialized argv pointer in task info The TCB initializes the pid early, but the argvstack is not initialized at that time. This may cause invalid addresses to be obtained when nxsched_get_stackargs is called during task enumeration. Initialize the argv pointer to NULL to enable safe validity checks. Signed-off-by: hujun5 --- include/nuttx/tls.h | 3 ++- sched/sched/sched_get_tls.c | 3 +-- sched/task/task_argvstr.c | 9 ++++++--- sched/task/task_setup.c | 3 +++ sched/tls/tls_dupinfo.c | 7 +++++++ sched/tls/tls_initinfo.c | 6 ++++++ 6 files changed, 25 insertions(+), 6 deletions(-) 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; }