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-apps.git

commit f75251f7e301bfbdb0f77005110449f6f3190a64
Author: Abhishek Mishra <[email protected]>
AuthorDate: Wed Aug 19 08:07:17 2026 +0000

    nshlib: close extra fds before jailed execvp
    
    chroot <newroot> <command> closes non-stdio, non-O_CLOEXEC descriptors
    before execvp so inherited host fds cannot bypass the jail.
    
    Signed-off-by: Abhishek Mishra <[email protected]>
---
 nshlib/nsh_envcmds.c | 36 ++++++++++++++++++++++++++++++++++++
 1 file changed, 36 insertions(+)

diff --git a/nshlib/nsh_envcmds.c b/nshlib/nsh_envcmds.c
index e8b0d0473..740c1fe19 100644
--- a/nshlib/nsh_envcmds.c
+++ b/nshlib/nsh_envcmds.c
@@ -30,6 +30,7 @@
 #include <unistd.h>
 #include <string.h>
 #include <ctype.h>
+#include <fcntl.h>
 #include <libgen.h>
 #include <errno.h>
 
@@ -324,6 +325,40 @@ errout:
 }
 #endif
 
+/****************************************************************************
+ * Name: nsh_chroot_closefds
+ *
+ * Description:
+ *   Close descriptors above stderr that are not already O_CLOEXEC so a
+ *   jailed execvp() child cannot inherit host file descriptors.
+ *
+ ****************************************************************************/
+
+#if defined(CONFIG_FS_CHROOT) && !defined(CONFIG_NSH_DISABLE_CHROOT) && \
+    defined(CONFIG_LIBC_EXECFUNCS)
+static void nsh_chroot_closefds(void)
+{
+  int fdmax;
+  int fd;
+  int flags;
+
+  fdmax = sysconf(_SC_OPEN_MAX);
+  if (fdmax <= STDERR_FILENO)
+    {
+      return;
+    }
+
+  for (fd = STDERR_FILENO + 1; fd < fdmax; fd++)
+    {
+      flags = fcntl(fd, F_GETFD);
+      if (flags >= 0 && (flags & FD_CLOEXEC) == 0)
+        {
+          close(fd);
+        }
+    }
+}
+#endif
+
 /****************************************************************************
  * Name: cmd_chroot
  ****************************************************************************/
@@ -366,6 +401,7 @@ int cmd_chroot(FAR struct nsh_vtbl_s *vtbl, int argc, FAR 
char **argv)
 #ifdef CONFIG_LIBC_EXECFUNCS
   if (argc > 2)
     {
+      nsh_chroot_closefds();
       execvp(argv[2], &argv[2]);
       nsh_error(vtbl, g_fmtcmdfailed, argv[0], "execvp", NSH_ERRNO);
       return ERROR;

Reply via email to