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


The following commit(s) were added to refs/heads/master by this push:
     new 47dfaad8057 sched/tls: Free the pthread_atfork() entries in the heap 
of the process.
47dfaad8057 is described below

commit 47dfaad80574edb11df710522029a4b11d03534b
Author: Marco Casaroli <[email protected]>
AuthorDate: Thu Oct 22 09:21:51 2026 +0200

    sched/tls: Free the pthread_atfork() entries in the heap of the process.
    
    pthread_atfork() allocates its entries with lib_malloc() in the heap of
    the calling process.  task_uninit_info() freed them with lib_free(),
    which is kmm_free() in the kernel.  In a protected or kernel build with
    CONFIG_PTHREAD_ATFORK, the exit of a process that called
    pthread_atfork() then gave a user pointer to the kernel heap: an
    assertion in kmm_free() with CONFIG_DEBUG_ASSERTIONS, else a corrupt
    kernel heap.
    
    Free the entries with group_free(), which selects the heap of the
    group.  In a kernel build, do not free the entries of an unprivileged
    group: they lie in its user heap, which goes away with its address
    environment (as task_uninit_stream() does for the streams).
    
    Assisted-by: Claude Code:claude-opus-5-5
    Signed-off-by: Marco Casaroli <[email protected]>
---
 sched/tls/task_uninitinfo.c | 16 +++++++++++++++-
 1 file changed, 15 insertions(+), 1 deletion(-)

diff --git a/sched/tls/task_uninitinfo.c b/sched/tls/task_uninitinfo.c
index 6212cce8551..b83f2f2f151 100644
--- a/sched/tls/task_uninitinfo.c
+++ b/sched/tls/task_uninitinfo.c
@@ -136,7 +136,21 @@ void task_uninit_info(FAR struct task_group_s *group)
       entry = list_first_entry(list,
                                struct pthread_atfork_s, node);
       list_delete_init(&entry->node);
-      lib_free(entry);
+
+      /* pthread_atfork() allocated the entry in the heap of the process:
+       * the user heap, unless the process is privileged.
+       */
+
+#ifdef CONFIG_BUILD_KERNEL
+      /* The user heap of an unprivileged group goes away with its address
+       * environment.
+       */
+
+      if ((group->tg_flags & GROUP_FLAG_PRIVILEGED) != 0)
+#endif
+        {
+          group_free(group, entry);
+        }
     }
 #endif
 

Reply via email to