From c87956837e962072fff61edef5b18e55ad42d730 Mon Sep 17 00:00:00 2001 From: "Richard W.M. Jones" Date: Tue, 26 Jun 2012 14:39:16 +0100 Subject: launch: Avoid double-close when qemu exits early. The stdin and stdout of the qemu process are aliased to g->fd: g->fd[0] = wfd[1]; g->fd[1] = rfd[0]; However if the child exits early, then child_cleanup closes g->fd[0], g->fd[1], AND the code at the cleanup1 label closes wfd[1], rfd[0], resulting in a double-close. Avoid this case by setting wfd[1], rfd[0] to -1. In the cleanup1 label, only close wfd[1], rfd[0] if they are not -1, and add the same for g->fd[0], g->fd[1]. --- src/launch.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/src/launch.c b/src/launch.c index 86e1bc56..3cd16f41 100644 --- a/src/launch.c +++ b/src/launch.c @@ -1018,6 +1018,7 @@ launch_appliance (guestfs_h *g) g->fd[0] = wfd[1]; /* stdin of child */ g->fd[1] = rfd[0]; /* stdout of child */ + wfd[1] = rfd[0] = -1; } else { g->fd[0] = open ("/dev/null", O_RDWR|O_CLOEXEC); if (g->fd[0] == -1) { @@ -1028,6 +1029,7 @@ launch_appliance (guestfs_h *g) if (g->fd[1] == -1) { perrorf (g, "dup"); close (g->fd[0]); + g->fd[0] = -1; goto cleanup1; } } @@ -1098,13 +1100,15 @@ launch_appliance (guestfs_h *g) cleanup1: if (!g->direct) { - close (wfd[1]); - close (rfd[0]); + if (wfd[1] >= 0) close (wfd[1]); + if (rfd[1] >= 0) close (rfd[0]); } if (g->pid > 0) kill (g->pid, 9); if (g->recoverypid > 0) kill (g->recoverypid, 9); if (g->pid > 0) waitpid (g->pid, NULL, 0); if (g->recoverypid > 0) waitpid (g->recoverypid, NULL, 0); + if (g->fd[0] >= 0) close (g->fd[0]); + if (g->fd[1] >= 0) close (g->fd[1]); g->fd[0] = -1; g->fd[1] = -1; g->pid = 0; -- cgit