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 36562a7c2efd63d7b109c7719e845602a3cdca45 Author: Marco Casaroli <[email protected]> AuthorDate: Mon Oct 12 05:55:30 2026 +0200 libs/libc/environ: Allocate the environment in the heap of its task. The environment functions now run in kernel code as well as in user code. In kernel code lib_umalloc() is kumm_malloc(), the heap of the current user process. A kernel build then faulted at boot: the idle task sets PATH before any user process exists. The environment of a kernel thread is in the kernel heap, with its task information. Allocate and free each environment in the heap that holds its task information: the kernel heap for a kernel thread, the user heap for a user task. User code still uses lib_umalloc(). putenv() allocates and frees its copy of the string the same way. Assisted-by: Claude Code:claude-opus-5-5 Signed-off-by: Marco Casaroli <[email protected]> --- libs/libc/environ/env_dup.c | 8 ++++---- libs/libc/environ/env_putenv.c | 12 ++++++++++-- libs/libc/environ/env_release.c | 4 ++-- libs/libc/environ/env_removevar.c | 6 +++--- libs/libc/environ/env_setenv.c | 8 ++++---- libs/libc/environ/environ.h | 23 +++++++++++++++++++++++ 6 files changed, 46 insertions(+), 15 deletions(-) diff --git a/libs/libc/environ/env_dup.c b/libs/libc/environ/env_dup.c index 220392d24a5..be85a18f564 100644 --- a/libs/libc/environ/env_dup.c +++ b/libs/libc/environ/env_dup.c @@ -95,7 +95,7 @@ int env_dup(FAR struct task_info_s *info, FAR char * const *envcp) { /* There is an environment, duplicate it */ - envp = lib_umalloc(sizeof(*envp) * info->ta_envpc); + envp = env_malloc(info, sizeof(*envp) * info->ta_envpc); if (envp == NULL) { /* The parent's environment can not be inherited due to a @@ -113,15 +113,15 @@ int env_dup(FAR struct task_info_s *info, FAR char * const *envcp) while (envc-- > 0) { size = strlen(envcp[envc]) + 1; - envp[envc] = lib_umalloc(size); + envp[envc] = env_malloc(info, size); if (envp[envc] == NULL) { while (envp[++envc] != NULL) { - lib_ufree(envp[envc]); + env_free(info, envp[envc]); } - lib_ufree(envp); + env_free(info, envp); envp = NULL; ret = -ENOMEM; break; diff --git a/libs/libc/environ/env_putenv.c b/libs/libc/environ/env_putenv.c index bc4c330d232..5f0e29155af 100644 --- a/libs/libc/environ/env_putenv.c +++ b/libs/libc/environ/env_putenv.c @@ -28,6 +28,9 @@ #include <errno.h> #include <nuttx/lib/lib.h> +#include <nuttx/tls.h> + +#include "environ.h" /**************************************************************************** * Public Functions @@ -57,8 +60,10 @@ int putenv(FAR const char *string) { + FAR struct task_info_s *info = task_get_info(); FAR char *pname; FAR char *pequal; + size_t len; int ret = OK; /* Verify that a string was passed */ @@ -71,13 +76,16 @@ int putenv(FAR const char *string) /* Parse the name=value string */ - pname = strdup(string); + len = strlen(string) + 1; + pname = env_malloc(info, len); if (!pname) { ret = ENOMEM; goto errout; } + memcpy(pname, string, len); + pequal = strchr(pname, '='); if (pequal) { @@ -87,7 +95,7 @@ int putenv(FAR const char *string) ret = setenv(pname, pequal + 1, TRUE); } - lib_ufree(pname); + env_free(info, pname); return ret; errout: diff --git a/libs/libc/environ/env_release.c b/libs/libc/environ/env_release.c index 2728fd95aa1..4c1abfcd49a 100644 --- a/libs/libc/environ/env_release.c +++ b/libs/libc/environ/env_release.c @@ -67,12 +67,12 @@ void env_release(FAR struct task_info_s *info) for (i = 0; info->ta_envp[i] != NULL; i++) { - lib_ufree(info->ta_envp[i]); + env_free(info, info->ta_envp[i]); } /* Free the environment */ - lib_ufree(info->ta_envp); + env_free(info, info->ta_envp); } /* In any event, make sure that all environment-related variables in the diff --git a/libs/libc/environ/env_removevar.c b/libs/libc/environ/env_removevar.c index 4c4f5e5432b..207e0468b01 100644 --- a/libs/libc/environ/env_removevar.c +++ b/libs/libc/environ/env_removevar.c @@ -61,7 +61,7 @@ void env_removevar(FAR struct task_info_s *info, ssize_t index) /* Free the allocate environment string */ - lib_ufree(info->ta_envp[index]); + env_free(info, info->ta_envp[index]); /* Exchange the last env and the index env */ @@ -80,7 +80,7 @@ void env_removevar(FAR struct task_info_s *info, ssize_t index) if (info->ta_envc == 0) { - lib_ufree(info->ta_envp); + env_free(info, info->ta_envp); info->ta_envp = NULL; info->ta_envpc = 0; } @@ -91,7 +91,7 @@ void env_removevar(FAR struct task_info_s *info, ssize_t index) info->ta_envpc = info->ta_envc + SCHED_ENVIRON_RESERVED + 1; - info->ta_envp = lib_urealloc(info->ta_envp, + info->ta_envp = env_realloc(info, info->ta_envp, sizeof(*info->ta_envp) * info->ta_envpc); DEBUGASSERT(info->ta_envp != NULL); } diff --git a/libs/libc/environ/env_setenv.c b/libs/libc/environ/env_setenv.c index 0d2564b1b57..7bd5a1748db 100644 --- a/libs/libc/environ/env_setenv.c +++ b/libs/libc/environ/env_setenv.c @@ -143,7 +143,7 @@ int setenv(FAR const char *name, FAR const char *value, int overwrite) /* Then allocate or reallocate the environment buffer */ - pvar = lib_umalloc(varlen); + pvar = env_malloc(info, varlen); if (pvar == NULL) { ret = ENOMEM; @@ -156,7 +156,7 @@ int setenv(FAR const char *name, FAR const char *value, int overwrite) { envpc = SCHED_ENVIRON_RESERVED + 2; - envp = lib_umalloc(sizeof(*envp) * envpc); + envp = env_malloc(info, sizeof(*envp) * envpc); if (envp == NULL) { ret = ENOMEM; @@ -170,7 +170,7 @@ int setenv(FAR const char *name, FAR const char *value, int overwrite) { envpc = envc + SCHED_ENVIRON_RESERVED + 2; - envp = lib_urealloc(info->ta_envp, sizeof(*envp) * envpc); + envp = env_realloc(info, info->ta_envp, sizeof(*envp) * envpc); if (envp == NULL) { ret = ENOMEM; @@ -194,7 +194,7 @@ int setenv(FAR const char *name, FAR const char *value, int overwrite) return OK; errout_with_var: - lib_ufree(pvar); + env_free(info, pvar); errout_with_lock: nxrmutex_unlock(&info->ta_lock); errout: diff --git a/libs/libc/environ/environ.h b/libs/libc/environ/environ.h index 475007c9754..2b5f2888b5b 100644 --- a/libs/libc/environ/environ.h +++ b/libs/libc/environ/environ.h @@ -33,6 +33,10 @@ #include <nuttx/lib/lib.h> +#ifdef __KERNEL__ +# include <nuttx/kmalloc.h> +#endif + /**************************************************************************** * Pre-processor Definitions ****************************************************************************/ @@ -41,6 +45,25 @@ # define SCHED_ENVIRON_RESERVED (4) +/* The environment is in the heap that holds the task information: the + * kernel heap for a kernel thread, the user heap for a user task. Kernel + * code also changes the environment of kernel threads (the idle task at + * boot) and of a new user task. + */ + +# ifdef __KERNEL__ +# define env_malloc(info, n) \ + (kmm_heapmember(info) ? kmm_malloc(n) : kumm_malloc(n)) +# define env_realloc(info, p, n) \ + (kmm_heapmember(info) ? kmm_realloc(p, n) : kumm_realloc(p, n)) +# define env_free(info, p) \ + (kmm_heapmember(info) ? kmm_free(p) : kumm_free(p)) +# else +# define env_malloc(info, n) ((void)(info), lib_umalloc(n)) +# define env_realloc(info, p, n) ((void)(info), lib_urealloc(p, n)) +# define env_free(info, p) ((void)(info), lib_ufree(p)) +# endif + /**************************************************************************** * Public Data ****************************************************************************/
