From 1c553ea3cd03017547a25221db79c423c83d1005 Mon Sep 17 00:00:00 2001 From: Pino Toscano Date: Thu, 19 Nov 2015 17:34:11 +0100 Subject: [PATCH 1/5] daemon: always provide stdin when running chroot commands (RHBZ#1280029) When running commands in the mounted guest (using the "command" API, and APIs based on it), provide the /dev/null from the appliance as open fd for stdin. Commands usually assume stdin is open if they didn't close it explicitly, so this should avoid crashes or misbehavings due to that. (cherry picked from commit fd2f175ee79d29df101d353e2f380db27b19553a) --- daemon/command.c | 19 +++++++++++++++++-- 1 file changed, 17 insertions(+), 2 deletions(-) diff --git a/daemon/command.c b/daemon/command.c index 1593de9..27a4d0c 100644 --- a/daemon/command.c +++ b/daemon/command.c @@ -23,6 +23,8 @@ #include #include #include +#include +#include #include "guestfs_protocol.h" #include "daemon.h" @@ -242,7 +244,7 @@ do_command (char *const *argv) { char *out; CLEANUP_FREE char *err = NULL; - int r; + int r, dev_null_fd, flags; CLEANUP_BIND_STATE struct bind_state bind_state = { .mounted = false }; CLEANUP_RESOLVER_STATE struct resolver_state resolver_state = { .mounted = false }; @@ -259,6 +261,17 @@ do_command (char *const *argv) return NULL; } + /* Provide /dev/null as stdin for the command, since we want + * to make sure processes have an open stdin, and it is not + * possible to rely on the guest to provide it (Linux guests + * get /dev dynamically populated at runtime by udev). + */ + dev_null_fd = open ("/dev/null", O_RDONLY|O_CLOEXEC); + if (dev_null_fd == -1) { + reply_with_perror ("/dev/null"); + return NULL; + } + if (bind_mount (&bind_state) == -1) return NULL; if (enable_network) { @@ -266,8 +279,10 @@ do_command (char *const *argv) return NULL; } + flags = COMMAND_FLAG_CHROOT_COPY_FILE_TO_STDIN | dev_null_fd; + CHROOT_IN; - r = commandv (&out, &err, (const char * const *) argv); + r = commandvf (&out, &err, flags, (const char * const *) argv); CHROOT_OUT; free_bind_state (&bind_state); -- 2.5.0