This is an automated email from the ASF dual-hosted git repository.
xiaoxiang781216 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 c642e99b340 binfmt: Update the TLS pid when exec() swaps the pids.
c642e99b340 is described below
commit c642e99b340c32642fec0a99aba58115c499e9ac
Author: Marco Casaroli <[email protected]>
AuthorDate: Tue Oct 6 18:15:38 2026 +0200
binfmt: Update the TLS pid when exec() swaps the pids.
exec() swaps the pids of the caller and the new task, so that the new
program keeps the pid of the caller. exec_swap() changes tcb->pid and
group->tg_pid. But getpid() and gettid() read the copies in TLS,
tg_info->ta_pid and tl_tid, and exec_swap() does not change them. So
getpid() in the new program returns the pid that the caller has now, and
kill(getpid(), sig) sends the signal to the caller.
Make exec_swap() update both copies for both tasks. The address
environment of the new task is current in exec_swap(). The TLS of the
caller is in the address environment of the caller, so exec_swap()
selects that environment for the update of the caller.
Assisted-by: Claude Code:claude-opus-5-5
Signed-off-by: Marco Casaroli <[email protected]>
---
binfmt/binfmt_execmodule.c | 26 ++++++++++++++++++++++++++
1 file changed, 26 insertions(+)
diff --git a/binfmt/binfmt_execmodule.c b/binfmt/binfmt_execmodule.c
index 867091c61a0..d27218a9233 100644
--- a/binfmt/binfmt_execmodule.c
+++ b/binfmt/binfmt_execmodule.c
@@ -39,6 +39,7 @@
#include <nuttx/fs/fs.h>
#include <nuttx/kmalloc.h>
#include <nuttx/sched.h>
+#include <nuttx/tls.h>
#include <sched/sched.h>
#include <task/spawn.h>
#include <nuttx/spawn.h>
@@ -78,6 +79,10 @@ static void exec_swap(FAR struct tcb_s *ptcb, FAR struct
tcb_s *chtcb)
int chndx;
pid_t pid;
irqstate_t flags;
+ FAR struct tls_info_s *info;
+#if defined(CONFIG_ARCH_ADDRENV) && defined(CONFIG_BUILD_KERNEL)
+ FAR struct addrenv_s *oldenv;
+#endif
#ifdef CONFIG_SCHED_HAVE_PARENT
# ifdef CONFIG_SCHED_CHILD_STATUS
FAR struct child_status_s *tg_children;
@@ -131,6 +136,27 @@ static void exec_swap(FAR struct tcb_s *ptcb, FAR struct
tcb_s *chtcb)
#endif
leave_critical_section(flags);
+
+ /* getpid() and gettid() read copies of the pids in TLS. The address
+ * environment of the child is current here, and the TLS of the caller
+ * is in its own.
+ */
+
+ info = (FAR struct tls_info_s *)chtcb->stack_alloc_ptr;
+ info->tl_tid = chtcb->pid;
+ chtcb->group->tg_info->ta_pid = chtcb->group->tg_pid;
+
+#if defined(CONFIG_ARCH_ADDRENV) && defined(CONFIG_BUILD_KERNEL)
+ addrenv_select(ptcb->addrenv_own, &oldenv);
+#endif
+
+ info = (FAR struct tls_info_s *)ptcb->stack_alloc_ptr;
+ info->tl_tid = ptcb->pid;
+ ptcb->group->tg_info->ta_pid = ptcb->group->tg_pid;
+
+#if defined(CONFIG_ARCH_ADDRENV) && defined(CONFIG_BUILD_KERNEL)
+ addrenv_restore(oldenv);
+#endif
}
/****************************************************************************