Matthew Booth
2012-Dec-13 16:03 UTC
[Libguestfs] [PATCH] daemon: fix directory outside current root when executing commands
When executing a command, we temporarily chroot, fork and exec the command, then chroot back. We intentionally don't chdir in the parent process so that we can 'jailbreak' the chroot later. However, this has the effect that commands are executed with a current working directory which is outside the current root. This unusual state can cause errors in executed commands which don't anticipate it. This change does a chdir("/") before executing and command. This happens inside the fork, so the jailbreak isn't affected in the parent. --- .gitignore | 1 + daemon/guestfsd.c | 2 ++ generator/actions.ml | 7 ++++++- tests/c-api/Makefile.am | 6 +++++- tests/c-api/test-pwd.c | 35 +++++++++++++++++++++++++++++++++++ 5 files changed, 49 insertions(+), 2 deletions(-) create mode 100644 tests/c-api/test-pwd.c diff --git a/.gitignore b/.gitignore index 4a5f0c1..3873a19 100644 --- a/.gitignore +++ b/.gitignore @@ -404,6 +404,7 @@ Makefile.in /tests/c-api/test-last-errno /tests/c-api/test.log /tests/c-api/test-private-data +/tests/c-api/test-pwd /tests/c-api/tests /tests/c-api/tests.c /tests/c-api/test*.tmp diff --git a/daemon/guestfsd.c b/daemon/guestfsd.c index 7e83a2a..1cbf82c 100644 --- a/daemon/guestfsd.c +++ b/daemon/guestfsd.c @@ -846,6 +846,8 @@ commandrvf (char **stdoutput, char **stderror, int flags, close (so_fd[PIPE_WRITE]); close (se_fd[PIPE_WRITE]); + chdir("/"); + execvp (argv[0], (void *) argv); perror (argv[0]); _exit (EXIT_FAILURE); diff --git a/generator/actions.ml b/generator/actions.ml index 2e815fc..f78d851 100644 --- a/generator/actions.ml +++ b/generator/actions.ml @@ -3687,7 +3687,12 @@ C<guestfs_is_file>, C<guestfs_is_blockdev> (etc), C<guestfs_is_zero>." }; [["mkdir"; "/command12"]; ["upload"; "test-command"; "/command12/test-command"]; ["chmod"; "0o755"; "/command12/test-command"]; - ["command"; "/command12/test-command"]]) + ["command"; "/command12/test-command"]]); + InitScratchFS, Always, TestOutput ( + [["mkdir"; "/pwd"]; + ["upload"; "test-pwd"; "/pwd/test-pwd"]; + ["chmod"; "0o755"; "/pwd/test-pwd"]; + ["command"; "/pwd/test-pwd"]], "/"); ]; shortdesc = "run a command from the guest filesystem"; longdesc = "\ diff --git a/tests/c-api/Makefile.am b/tests/c-api/Makefile.am index 762c0de..1b88581 100644 --- a/tests/c-api/Makefile.am +++ b/tests/c-api/Makefile.am @@ -34,7 +34,8 @@ check_PROGRAMS = \ test-private-data \ test-user-cancel \ test-debug-to-file \ - test-environment + test-environment \ + test-pwd TESTS = \ tests \ @@ -80,6 +81,9 @@ tests_LDADD = $(top_builddir)/src/libguestfs.la test_command_SOURCES = test-command.c test_command_LDFLAGS = -all-static +test_pwd_SOURCES = test-pwd.c +test_pwd_LDFLAGS = -all-static + # Hand-written C API tests. test_just_header_SOURCES = test-just-header.c diff --git a/tests/c-api/test-pwd.c b/tests/c-api/test-pwd.c new file mode 100644 index 0000000..60b978c --- /dev/null +++ b/tests/c-api/test-pwd.c @@ -0,0 +1,35 @@ +/* libguestfs + * Copyright (C) 2012 Red Hat Inc. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ + +/* This program, which must be statically linked, is used to test the + * guestfs_command and guestfs_command_lines functions. + */ + +#include <config.h> +#include <stdio.h> +#include <stdlib.h> +#include <unistd.h> + +int +main (int argc, char *argv[]) +{ + char *cwd = get_current_dir_name(); + printf("%s", cwd); + + exit (EXIT_SUCCESS); +} -- 1.7.11.7
Richard W.M. Jones
2012-Dec-13 17:23 UTC
[Libguestfs] [PATCH] daemon: fix directory outside current root when executing commands
Thanks, I will push this later. I made a couple of changes: (1) Ignore the return value of chdir (see ./configure --enable-gcc-warnings) (2) Skip this test if we weren't able to link test-pwd statically. Rich. -- Richard Jones, Virtualization Group, Red Hat http://people.redhat.com/~rjones virt-p2v converts physical machines to virtual machines. Boot with a live CD or over the network (PXE) and turn machines into Xen guests. http://et.redhat.com/~rjones/virt-p2v
Apparently Analagous Threads
- [PATCH 1/2] daemon: NFC Use symbolic names in commandrvf
- Re: [PATCH] daemon: improve internal commandrvf
- [PATCH] daemon: improve internal commandrvf
- [PATCH v3 2/6] daemon: Split out command() functions and CLEANUP_* macros into separate files.
- [PATCH] daemon: improve debugging for "stdout on stderr" flag