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

Reply via email to