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
commit e1dc2741b39c524121d44b7484c48d98039a489f Author: guoshichao <[email protected]> AuthorDate: Mon Nov 10 21:58:29 2025 +0800 environ: change the tg_en* from task_group_s to task_info_s Since tg_envp is placed in task_info_s, both tg_envp itself and the memory it points to (group_malloc) are userspace memory. There's no need to switch to kernel mode to access tg_env, which can improve access speed. Signed-off-by: guoshichao <[email protected]> (cherry picked from commit e60e6de82f6bf1e72139fcdba73ff3e26b951869 in https://github.com/open-vela/nuttx) Port to Apache master: env_sanitize_secure() (env_secureexec.c, added later on master) also reads the environment from the task info. Assisted-by: Claude Code:claude-opus-5-5 Signed-off-by: Marco Casaroli <[email protected]> --- include/nuttx/sched.h | 8 -------- include/nuttx/tls.h | 7 +++++++ sched/environ/env_dup.c | 17 ++++++++++------ sched/environ/env_findvar.c | 13 +++++++++---- sched/environ/env_foreach.c | 14 ++++++++----- sched/environ/env_getenv.c | 5 ++++- sched/environ/env_getenvironptr.c | 4 +++- sched/environ/env_release.c | 20 +++++++++++-------- sched/environ/env_removevar.c | 41 +++++++++++++++++++++++---------------- sched/environ/env_secureexec.c | 11 ++++++++--- sched/environ/env_setenv.c | 33 ++++++++++++++++++------------- sched/group/group_leave.c | 8 ++++---- 12 files changed, 110 insertions(+), 71 deletions(-) diff --git a/include/nuttx/sched.h b/include/nuttx/sched.h index ddb650e2d9f..76ea460379e 100644 --- a/include/nuttx/sched.h +++ b/include/nuttx/sched.h @@ -535,14 +535,6 @@ struct task_group_s sigset_t tg_sigdefault; /* Set of signals set to the default action */ #endif -#ifndef CONFIG_DISABLE_ENVIRON - /* Environment variables **************************************************/ - - FAR char **tg_envp; /* Allocated environment strings */ - ssize_t tg_envpc; /* Maximum entries of environment array */ - ssize_t tg_envc; /* Number of environment strings */ -#endif - #ifndef CONFIG_DISABLE_POSIX_TIMERS /* Interval timer *********************************************************/ diff --git a/include/nuttx/tls.h b/include/nuttx/tls.h index 256bfd15a14..e0464b3248e 100644 --- a/include/nuttx/tls.h +++ b/include/nuttx/tls.h @@ -162,6 +162,13 @@ struct task_info_s struct list_node ta_atfork; /* Holds the pthread_atfork_s list */ #endif pid_t ta_pid; /* Process ID */ +#ifndef CONFIG_DISABLE_ENVIRON + /* Environment variables **************************************************/ + + FAR char **ta_envp; /* Allocated environment strings */ + ssize_t ta_envpc; /* Maximum entries of environment array */ + ssize_t ta_envc; /* Number of environment strings */ +#endif }; /* struct tls_cleanup_s *****************************************************/ diff --git a/sched/environ/env_dup.c b/sched/environ/env_dup.c index ae58b2a63f8..d2f16bc8dd0 100644 --- a/sched/environ/env_dup.c +++ b/sched/environ/env_dup.c @@ -35,6 +35,8 @@ #include <errno.h> #include <nuttx/kmalloc.h> +#include <nuttx/mutex.h> +#include <nuttx/tls.h> #include "sched/sched.h" #include "environ/environ.h" @@ -65,16 +67,19 @@ int env_dup(FAR struct task_group_s *group, FAR char * const *envcp) { + FAR struct task_info_s *info; FAR char **envp = NULL; size_t envc = 0; size_t size; int ret = OK; - DEBUGASSERT(group != NULL); + DEBUGASSERT(group != NULL && group->tg_info != NULL); + + info = group->tg_info; /* Is there an environment ? */ - if (envcp != NULL && group->tg_envp == NULL) + if (envcp != NULL && info->ta_envp == NULL) { /* Pre-emption must be disabled throughout the following because the * environment may be shared. @@ -89,8 +94,8 @@ int env_dup(FAR struct task_group_s *group, FAR char * const *envcp) envc++; } - group->tg_envc = envc; - group->tg_envpc = (envc + SCHED_ENVIRON_RESERVED + 1); + info->ta_envc = envc; + info->ta_envpc = (envc + SCHED_ENVIRON_RESERVED + 1); /* A special case is that the parent has an "empty" environment * allocation, i.e., there is an allocation in place but it @@ -101,7 +106,7 @@ int env_dup(FAR struct task_group_s *group, FAR char * const *envcp) { /* There is an environment, duplicate it */ - envp = group_malloc(group, sizeof(*envp) * group->tg_envpc); + envp = group_malloc(group, sizeof(*envp) * info->ta_envpc); if (envp == NULL) { /* The parent's environment can not be inherited due to a @@ -140,7 +145,7 @@ int env_dup(FAR struct task_group_s *group, FAR char * const *envcp) /* Save the child environment allocation. */ - group->tg_envp = envp; + info->ta_envp = envp; nxrmutex_unlock(&group->tg_mutex); } diff --git a/sched/environ/env_findvar.c b/sched/environ/env_findvar.c index 0a2f5413420..a0879a5454a 100644 --- a/sched/environ/env_findvar.c +++ b/sched/environ/env_findvar.c @@ -33,6 +33,8 @@ #include <sched.h> #include <assert.h> +#include <nuttx/tls.h> + #include "environ/environ.h" /**************************************************************************** @@ -87,22 +89,25 @@ static bool env_cmpname(const char *pszname, const char *peqname) ssize_t env_findvar(FAR struct task_group_s *group, FAR const char *pname) { + FAR struct task_info_s *info; ssize_t i; /* Verify input parameters */ - DEBUGASSERT(group != NULL && pname != NULL); + DEBUGASSERT(group != NULL && group->tg_info != NULL && pname != NULL); + + info = group->tg_info; - if (group->tg_envp == NULL) + if (info->ta_envp == NULL) { return -ENOENT; } /* Search for a name=value string with matching name */ - for (i = 0; group->tg_envp[i] != NULL; i++) + for (i = 0; info->ta_envp[i] != NULL; i++) { - if (env_cmpname(pname, group->tg_envp[i])) + if (env_cmpname(pname, info->ta_envp[i])) { return i; } diff --git a/sched/environ/env_foreach.c b/sched/environ/env_foreach.c index 5569bc2ca25..b552549bc4d 100644 --- a/sched/environ/env_foreach.c +++ b/sched/environ/env_foreach.c @@ -34,6 +34,7 @@ #include <assert.h> #include <nuttx/environ.h> +#include <nuttx/tls.h> #include "environ/environ.h" @@ -67,23 +68,26 @@ int env_foreach(FAR struct task_group_s *group, env_foreach_t cb, FAR void *arg) { + FAR struct task_info_s *info; int ret = OK; size_t i; /* Verify input parameters */ - DEBUGASSERT(group != NULL && cb != NULL); + DEBUGASSERT(group != NULL && group->tg_info != NULL && cb != NULL); - if (group->tg_envp == NULL) + info = group->tg_info; + + if (info->ta_envp == NULL) { return ret; } - for (i = 0; group->tg_envp[i] != NULL; i++) + for (i = 0; info->ta_envp[i] != NULL; i++) { /* Perform the callback */ - ret = cb(arg, group->tg_envp[i]); + ret = cb(arg, info->ta_envp[i]); /* Terminate the traversal early if the callback so requests by * returning a non-zero value. @@ -95,7 +99,7 @@ int env_foreach(FAR struct task_group_s *group, } } - DEBUGASSERT(ret != OK || group->tg_envc == i); + DEBUGASSERT(ret != OK || info->ta_envc == i); return ret; } diff --git a/sched/environ/env_getenv.c b/sched/environ/env_getenv.c index 248fc4198f3..34142490f7a 100644 --- a/sched/environ/env_getenv.c +++ b/sched/environ/env_getenv.c @@ -33,6 +33,9 @@ #include <stdlib.h> #include <errno.h> +#include <nuttx/mutex.h> +#include <nuttx/tls.h> + #include "sched/sched.h" #include "environ/environ.h" @@ -95,7 +98,7 @@ FAR char *getenv(FAR const char *name) /* It does! Get the value sub-string from the name=value string */ - pvalue = strchr(group->tg_envp[ret], '='); + pvalue = strchr(group->tg_info->ta_envp[ret], '='); if (pvalue == NULL) { nxrmutex_unlock(&group->tg_mutex); diff --git a/sched/environ/env_getenvironptr.c b/sched/environ/env_getenvironptr.c index d1e930f566e..bf5be54bc30 100644 --- a/sched/environ/env_getenvironptr.c +++ b/sched/environ/env_getenvironptr.c @@ -30,6 +30,8 @@ #include <sched.h> #include <stdlib.h> +#include <nuttx/tls.h> + #include "sched/sched.h" #undef get_environ_ptr @@ -58,7 +60,7 @@ FAR char **get_environ_ptr(void) { FAR struct tcb_s *tcb = this_task(); - return tcb->group->tg_envp; + return tcb->group->tg_info->ta_envp; } #endif /* CONFIG_DISABLE_ENVIRON */ diff --git a/sched/environ/env_release.c b/sched/environ/env_release.c index 6ada8bf7908..d9b090662c7 100644 --- a/sched/environ/env_release.c +++ b/sched/environ/env_release.c @@ -33,6 +33,7 @@ #include <errno.h> #include <nuttx/kmalloc.h> +#include <nuttx/tls.h> #include "environ/environ.h" @@ -63,31 +64,34 @@ void env_release(FAR struct task_group_s *group) { + FAR struct task_info_s *info; int i; - DEBUGASSERT(group != NULL); + DEBUGASSERT(group != NULL && group->tg_info != NULL); - if (group->tg_envp) + info = group->tg_info; + + if (info->ta_envp) { /* Free any allocate environment strings */ - for (i = 0; group->tg_envp[i] != NULL; i++) + for (i = 0; info->ta_envp[i] != NULL; i++) { - group_free(group, group->tg_envp[i]); + group_free(group, info->ta_envp[i]); } /* Free the environment */ - group_free(group, group->tg_envp); + group_free(group, info->ta_envp); } /* In any event, make sure that all environment-related variables in the * task group structure are reset to initial values. */ - group->tg_envp = NULL; - group->tg_envpc = 0; - group->tg_envc = 0; + info->ta_envp = NULL; + info->ta_envpc = 0; + info->ta_envc = 0; } #endif /* CONFIG_DISABLE_ENVIRON */ diff --git a/sched/environ/env_removevar.c b/sched/environ/env_removevar.c index 5a08042ac4e..fd6eb0ef994 100644 --- a/sched/environ/env_removevar.c +++ b/sched/environ/env_removevar.c @@ -33,6 +33,7 @@ #include <assert.h> #include <nuttx/kmalloc.h> +#include <nuttx/tls.h> #include "environ/environ.h" @@ -63,43 +64,49 @@ void env_removevar(FAR struct task_group_s *group, ssize_t index) { - DEBUGASSERT(group != NULL && index >= 0 && index < group->tg_envc); + FAR struct task_info_s *info; + + DEBUGASSERT(group != NULL && group->tg_info != NULL); + + info = group->tg_info; + + DEBUGASSERT(index >= 0 && index < info->ta_envc); /* Free the allocate environment string */ - group_free(group, group->tg_envp[index]); + group_free(group, info->ta_envp[index]); /* Exchange the last env and the index env */ - group->tg_envc--; - if (index == group->tg_envc) + info->ta_envc--; + if (index == info->ta_envc) { - group->tg_envp[index] = NULL; + info->ta_envp[index] = NULL; } else { - group->tg_envp[index] = group->tg_envp[group->tg_envc]; - group->tg_envp[group->tg_envc] = NULL; + info->ta_envp[index] = info->ta_envp[info->ta_envc]; + info->ta_envp[info->ta_envc] = NULL; } /* Free the old environment (if there was one) */ - if (group->tg_envc == 0) + if (info->ta_envc == 0) { - group_free(group, group->tg_envp); - group->tg_envp = NULL; - group->tg_envpc = 0; + group_free(group, info->ta_envp); + info->ta_envp = NULL; + info->ta_envpc = 0; } - else if (group->tg_envc <= - (group->tg_envpc - SCHED_ENVIRON_RESERVED * 2)) + else if (info->ta_envc <= + (info->ta_envpc - SCHED_ENVIRON_RESERVED * 2)) { /* Reallocate the environment to reclaim a little memory */ - group->tg_envpc = group->tg_envc + SCHED_ENVIRON_RESERVED + 1; + info->ta_envpc = info->ta_envc + SCHED_ENVIRON_RESERVED + 1; - group->tg_envp = group_realloc(group, group->tg_envp, - sizeof(*group->tg_envp) * group->tg_envpc); - DEBUGASSERT(group->tg_envp != NULL); + info->ta_envp = group_realloc(group, info->ta_envp, + sizeof(*info->ta_envp) * info->ta_envpc); + DEBUGASSERT(info->ta_envp != NULL); } } diff --git a/sched/environ/env_secureexec.c b/sched/environ/env_secureexec.c index 5315f496c14..231fd54ba37 100644 --- a/sched/environ/env_secureexec.c +++ b/sched/environ/env_secureexec.c @@ -31,6 +31,8 @@ #include <stdlib.h> #include <assert.h> +#include <nuttx/tls.h> + #include "sched/sched.h" #include "environ/environ.h" @@ -99,15 +101,18 @@ static bool env_is_unsafe(FAR const char *pair) #ifdef CONFIG_SCHED_USER_IDENTITY void env_sanitize_secure(FAR struct task_group_s *group) { + FAR struct task_info_s *info; ssize_t index; - DEBUGASSERT(group != NULL); + DEBUGASSERT(group != NULL && group->tg_info != NULL); + + info = group->tg_info; nxrmutex_lock(&group->tg_mutex); - for (index = group->tg_envc - 1; index >= 0; ) + for (index = info->ta_envc - 1; index >= 0; ) { - FAR char *pair = group->tg_envp[index]; + FAR char *pair = info->ta_envp[index]; if (pair != NULL && env_is_unsafe(pair)) { diff --git a/sched/environ/env_setenv.c b/sched/environ/env_setenv.c index ea24bdad99e..115a45a68d6 100644 --- a/sched/environ/env_setenv.c +++ b/sched/environ/env_setenv.c @@ -36,6 +36,8 @@ #include <errno.h> #include <nuttx/kmalloc.h> +#include <nuttx/mutex.h> +#include <nuttx/tls.h> #include "sched/sched.h" #include "environ/environ.h" @@ -71,6 +73,7 @@ int setenv(FAR const char *name, FAR const char *value, int overwrite) { FAR struct tcb_s *rtcb; FAR struct task_group_s *group; + FAR struct task_info_s *info; FAR char *pvar; FAR char **envp; ssize_t envc; @@ -112,13 +115,15 @@ int setenv(FAR const char *name, FAR const char *value, int overwrite) rtcb = this_task(); group = rtcb->group; - DEBUGASSERT(group); + DEBUGASSERT(group && group->tg_info); + + info = group->tg_info; nxrmutex_lock(&group->tg_mutex); /* Check if the variable already exists */ - if (group->tg_envp && (ret = env_findvar(group, name)) >= 0) + if (info->ta_envp && (ret = env_findvar(group, name)) >= 0) { /* It does! Do we have permission to overwrite the existing value? */ @@ -140,7 +145,7 @@ int setenv(FAR const char *name, FAR const char *value, int overwrite) /* Check current envirments count */ - DEBUGASSERT(group->tg_envc < SSIZE_MAX); + DEBUGASSERT(info->ta_envc < SSIZE_MAX); /* Get the size of the new name=value string. * The +2 is for the '=' and for null terminator @@ -157,9 +162,9 @@ int setenv(FAR const char *name, FAR const char *value, int overwrite) goto errout_with_lock; } - envc = group->tg_envc; + envc = info->ta_envc; - if (group->tg_envp == NULL) + if (info->ta_envp == NULL) { envpc = SCHED_ENVIRON_RESERVED + 2; @@ -170,29 +175,29 @@ int setenv(FAR const char *name, FAR const char *value, int overwrite) goto errout_with_var; } - group->tg_envp = envp; - group->tg_envpc = envpc; + info->ta_envp = envp; + info->ta_envpc = envpc; } - else if (envc >= group->tg_envpc - 1) + else if (envc >= info->ta_envpc - 1) { envpc = envc + SCHED_ENVIRON_RESERVED + 2; - envp = group_realloc(group, group->tg_envp, sizeof(*envp) * envpc); + envp = group_realloc(group, info->ta_envp, sizeof(*envp) * envpc); if (envp == NULL) { ret = ENOMEM; goto errout_with_var; } - group->tg_envp = envp; - group->tg_envpc = envpc; + info->ta_envp = envp; + info->ta_envpc = envpc; } /* Save the new buffer and count */ - group->tg_envp[envc++] = pvar; - group->tg_envp[envc] = NULL; - group->tg_envc = envc; + info->ta_envp[envc++] = pvar; + info->ta_envp[envc] = NULL; + info->ta_envc = envc; /* Now, put the new name=value string into the environment buffer */ diff --git a/sched/group/group_leave.c b/sched/group/group_leave.c index 466f44be481..5752d1c4375 100644 --- a/sched/group/group_leave.c +++ b/sched/group/group_leave.c @@ -81,6 +81,10 @@ static inline void group_release(FAR struct task_group_s *group) nxrmutex_destroy(&group->tg_mutex); + /* Release all shared environment variables */ + + env_release(group); + task_uninit_info(group); #if defined(CONFIG_SCHED_HAVE_PARENT) && defined(CONFIG_SCHED_CHILD_STATUS) @@ -119,10 +123,6 @@ static inline void group_release(FAR struct task_group_s *group) } #endif - /* Release all shared environment variables */ - - env_release(group); - /* Destroy the mm_map list */ mm_map_destroy(&group->tg_mm_map);
