]> git.ipfire.org Git - thirdparty/valgrind.git/commitdiff
Close both internal pipe fds after VG_(fork) in parent and child
authorMark Wielaard <mark@klomp.org>
Sun, 16 Jun 2024 22:27:12 +0000 (00:27 +0200)
committerMark Wielaard <mark@klomp.org>
Mon, 17 Jun 2024 15:59:22 +0000 (17:59 +0200)
An VG_fork() creates a pipe between parent and child to syncronize the
two processes. The parent wants to register the child pid before the
child can run. This is done in register_sigchld_ignore.

Make sure both the parent and the child close both the read and write
file descriptors so none leak.

https://bugs.kde.org/show_bug.cgi?id=479661

coregrind/m_libcproc.c
none/tests/Makefile.am
none/tests/track-fds-exec-children.c [new file with mode: 0644]
none/tests/track-fds-exec-children.stderr.exp [new file with mode: 0644]
none/tests/track-fds-exec-children.vgtest [new file with mode: 0644]

index 11dabe768f590679c304a2898adb42e1dcbc76d7..8422e9d1187aa89ef594e94bf41c8a7e1141cba4 100644 (file)
@@ -905,6 +905,8 @@ static void register_sigchld_ignore ( Int pid, Int fds[2])
       return;
 
    if (pid == 0) {
+      /* We are the child, close writing fd that we don't use.  */
+      VG_(close)(fds[1]);
       /* Before proceeding, ensure parent has recorded child PID in map
          of SIGCHLD to ignore */
       while (child_wait == 1)
@@ -916,6 +918,7 @@ static void register_sigchld_ignore ( Int pid, Int fds[2])
          }
       }
 
+      /* Now close reading fd.  */
       VG_(close)(fds[0]);
       return;
    }
@@ -926,11 +929,15 @@ static void register_sigchld_ignore ( Int pid, Int fds[2])
       ht_sigchld_ignore = VG_(HT_construct)("ht.sigchld.ignore");
    VG_(HT_add_node)(ht_sigchld_ignore, n);
 
+   /* We are the parent process, close read fd that we don't use.  */
+   VG_(close)(fds[0]);
+
    child_wait = 0;
    if (VG_(write)(fds[1], &child_wait, sizeof(Int)) <= 0)
       VG_(message)(Vg_DebugMsg,
          "warning: Unable to record PID of internal process (write)\n");
 
+   /* Now close writing fd.  */
    VG_(close)(fds[1]);
 }
 
index 553a9c8655a189f429afd84b27f1820202185abb..8c1bc014bc3ad634547feaa9ec0c6b4eeeeb239a 100644 (file)
@@ -240,6 +240,7 @@ EXTRA_DIST = \
        threadederrno.vgtest \
        timestamp.stderr.exp timestamp.vgtest \
        tls.vgtest tls.stderr.exp tls.stdout.exp  \
+       track-fds-exec-children.vgtest track-fds-exec-children.stderr.exp \
        unit_debuglog.stderr.exp unit_debuglog.vgtest \
        vgprintf.stderr.exp vgprintf.vgtest \
        vgprintf_nvalgrind.stderr.exp vgprintf_nvalgrind.vgtest \
@@ -297,6 +298,7 @@ check_PROGRAMS = \
        tls \
        tls.so \
        tls2.so \
+       track-fds-exec-children \
        unit_debuglog \
        valgrind_cpp_test \
        vgprintf \
@@ -435,6 +437,7 @@ if VGCONF_OS_IS_DARWIN
 else
  tls2_so_LDFLAGS       = -shared
 endif
+track_fds_exec_children_SOURCES = track-fds-exec-children.c
 
 vgprintf_nvalgrind_SOURCES = vgprintf.c
 vgprintf_nvalgrind_CFLAGS = ${AM_CFLAGS} -DNVALGRIND
diff --git a/none/tests/track-fds-exec-children.c b/none/tests/track-fds-exec-children.c
new file mode 100644 (file)
index 0000000..7209ee7
--- /dev/null
@@ -0,0 +1,13 @@
+#include <unistd.h>
+#include <sys/wait.h>
+
+int main()
+{
+  pid_t pid = fork ();
+  if (pid == 0)
+    execlp("true", "true", NULL);
+
+  // Wait till true succeeds
+  wait (NULL);
+  return 0;
+}
diff --git a/none/tests/track-fds-exec-children.stderr.exp b/none/tests/track-fds-exec-children.stderr.exp
new file mode 100644 (file)
index 0000000..e69de29
diff --git a/none/tests/track-fds-exec-children.vgtest b/none/tests/track-fds-exec-children.vgtest
new file mode 100644 (file)
index 0000000..aa926a6
--- /dev/null
@@ -0,0 +1,3 @@
+env: DEBUGINFOD_URLS=file:/dev/null
+prog: track-fds-exec-children
+vgopts: -q --track-fds=yes --trace-children=yes