You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@nuttx.apache.org by ac...@apache.org on 2026/10/17 22:29:12 UTC

(nuttx) branch master updated: sched/task: Restore the parent environment only after a select in fork().

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 d7735832a90 sched/task: Restore the parent environment only after a select in fork().
d7735832a90 is described below

commit d7735832a9001e3cad6a8943a37f516a8140876c
Author: Marco Casaroli <ma...@gmail.com>
AuthorDate: Mon Oct 12 16:55:06 2026 +0200

    sched/task: Restore the parent environment only after a select in fork().
    
    When addrenv_fork() failed, nxtask_setup_fork() still called
    fork_restore_parent_env().  addrenv_restore() gave back a reference to
    the parent's address environment that addrenv_select() never took.
    When the parent exited, its address environment was destroyed while a
    CPU still had it selected, and the next switch to it found no page
    tables.
    
    Restore the parent's environment only if the child has one.
    
    Assisted-by: Claude Code:claude-opus-5-5
    Signed-off-by: Marco Casaroli <ma...@gmail.com>
---
 sched/task/task_fork.c | 9 +++++----
 1 file changed, 5 insertions(+), 4 deletions(-)

diff --git a/sched/task/task_fork.c b/sched/task/task_fork.c
index 0aabb955da7..8ac24a37573 100644
--- a/sched/task/task_fork.c
+++ b/sched/task/task_fork.c
@@ -432,12 +432,13 @@ FAR struct tcb_s *nxtask_setup_fork(start_t retaddr, bool vfork)
 
 errout_with_tcb:
 #if defined(CONFIG_ARCH_ADDRENV) && defined(CONFIG_ARCH_HAVE_FORK)
-  /* Get back into the parent's address environment before unwinding.  If the
-   * duplication above never happened this is the environment we are already
-   * in, and addrenv_restore() is then a no-op.
+  /* Get back into the parent's address environment before unwinding.  Only
+   * a successful duplication selected the child's environment: otherwise
+   * addrenv_restore() would give back a reference that was never taken.
    */
 
-  if (!vfork && ttype != TCB_FLAG_TTYPE_KERNEL)
+  if (!vfork && ttype != TCB_FLAG_TTYPE_KERNEL &&
+      child->addrenv_own != NULL)
     {
       fork_restore_parent_env();
     }