From: "Richard W.M. Jones" <rjones(a)redhat.com>
If the parent process uses a pipe (or any fd, but pipes are a
particular problem), then the recovery process would hold open the
file descriptor(s) of the pipe, meaning that it could not be fully
closed in the parent. Because the recovery process doesn't use
exec(2), this wasn't avoidable even using FD_CLOEXEC.
Avoid this by closing all file descriptors when starting the recovery
process.
---
src/launch.c | 12 ++++++++++++
1 files changed, 12 insertions(+), 0 deletions(-)
diff --git a/src/launch.c b/src/launch.c
index 1dc23f4..a9af445 100644
--- a/src/launch.c
+++ b/src/launch.c
@@ -844,9 +844,21 @@ launch_appliance (guestfs_h *g)
if (g->recovery_proc) {
r = fork ();
if (r == 0) {
+ int fd, max_fd;
pid_t qemu_pid = g->pid;
pid_t parent_pid = getppid ();
+ /* Close all other file descriptors. This ensures that we don't
+ * hold open (eg) pipes from the parent process.
+ */
+ max_fd = sysconf (_SC_OPEN_MAX);
+ if (max_fd == -1)
+ max_fd = 1024;
+ if (max_fd > 65536)
+ max_fd = 65536; /* bound the amount of work we do here */
+ for (fd = 0; fd < max_fd; ++fd)
+ close (fd);
+
/* It would be nice to be able to put this in the same process
* group as qemu (ie. setpgid (0, qemu_pid)). However this is
* not possible because we don't have any guarantee here that
--
1.7.9.1