提交 0858532e 编写于 作者: A aliguori

chroot and change user support (Nolan)

Resent with fixed formatting.

This patch adds two new command line options:
 -chroot <dir>
 -runas <user>

This is useful for running qemu as an unprivileged user in a chroot
jail.  To avoid having to populate the jail, chrooting happens right
before the start of guest execution.
Signed-off-by: NNolan Leake <nolan@sigbus.net>
Signed-off-by: NAnthony Liguori <aliguori@us.ibm.com>


git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@6652 c046a42c-6fe2-441c-8c8c-71466251a162
上级 8290edda
...@@ -1161,6 +1161,14 @@ character to Control-t. ...@@ -1161,6 +1161,14 @@ character to Control-t.
@item -echr 20 @item -echr 20
@end table @end table
@item -chroot dir
Immediately before starting guest execution, chroot to the specified
directory. Especially useful in combination with -runas.
@item -runas user
Immediately before starting guest execution, drop root privileges, switching
to the specified user.
@end table @end table
@c man end @c man end
......
...@@ -52,6 +52,7 @@ ...@@ -52,6 +52,7 @@
#include <zlib.h> #include <zlib.h>
#ifndef _WIN32 #ifndef _WIN32
#include <pwd.h>
#include <sys/times.h> #include <sys/times.h>
#include <sys/wait.h> #include <sys/wait.h>
#include <termios.h> #include <termios.h>
...@@ -4075,6 +4076,10 @@ static void help(int exitcode) ...@@ -4075,6 +4076,10 @@ static void help(int exitcode)
#endif #endif
"-tb-size n set TB size\n" "-tb-size n set TB size\n"
"-incoming p prepare for incoming migration, listen on port p\n" "-incoming p prepare for incoming migration, listen on port p\n"
#ifndef _WIN32
"-chroot dir Chroot to dir just before starting the VM.\n"
"-runas user Change to user id user just before starting the VM.\n"
#endif
"\n" "\n"
"During emulation, the following keys are useful:\n" "During emulation, the following keys are useful:\n"
"ctrl-alt-f toggle full screen\n" "ctrl-alt-f toggle full screen\n"
...@@ -4192,6 +4197,8 @@ enum { ...@@ -4192,6 +4197,8 @@ enum {
QEMU_OPTION_old_param, QEMU_OPTION_old_param,
QEMU_OPTION_tb_size, QEMU_OPTION_tb_size,
QEMU_OPTION_incoming, QEMU_OPTION_incoming,
QEMU_OPTION_chroot,
QEMU_OPTION_runas,
}; };
typedef struct QEMUOption { typedef struct QEMUOption {
...@@ -4322,6 +4329,8 @@ static const QEMUOption qemu_options[] = { ...@@ -4322,6 +4329,8 @@ static const QEMUOption qemu_options[] = {
#endif #endif
{ "tb-size", HAS_ARG, QEMU_OPTION_tb_size }, { "tb-size", HAS_ARG, QEMU_OPTION_tb_size },
{ "incoming", HAS_ARG, QEMU_OPTION_incoming }, { "incoming", HAS_ARG, QEMU_OPTION_incoming },
{ "chroot", HAS_ARG, QEMU_OPTION_chroot },
{ "runas", HAS_ARG, QEMU_OPTION_runas },
{ NULL }, { NULL },
}; };
...@@ -4632,6 +4641,10 @@ int main(int argc, char **argv, char **envp) ...@@ -4632,6 +4641,10 @@ int main(int argc, char **argv, char **envp)
const char *pid_file = NULL; const char *pid_file = NULL;
int autostart; int autostart;
const char *incoming = NULL; const char *incoming = NULL;
int fd;
struct passwd *pwd;
const char *chroot_dir = NULL;
const char *run_as = NULL;
qemu_cache_utils_init(envp); qemu_cache_utils_init(envp);
...@@ -5287,6 +5300,12 @@ int main(int argc, char **argv, char **envp) ...@@ -5287,6 +5300,12 @@ int main(int argc, char **argv, char **envp)
case QEMU_OPTION_incoming: case QEMU_OPTION_incoming:
incoming = optarg; incoming = optarg;
break; break;
case QEMU_OPTION_chroot:
chroot_dir = optarg;
break;
case QEMU_OPTION_runas:
run_as = optarg;
break;
} }
} }
} }
...@@ -5739,7 +5758,6 @@ int main(int argc, char **argv, char **envp) ...@@ -5739,7 +5758,6 @@ int main(int argc, char **argv, char **envp)
if (daemonize) { if (daemonize) {
uint8_t status = 0; uint8_t status = 0;
ssize_t len; ssize_t len;
int fd;
again1: again1:
len = write(fds[1], &status, 1); len = write(fds[1], &status, 1);
...@@ -5753,12 +5771,47 @@ int main(int argc, char **argv, char **envp) ...@@ -5753,12 +5771,47 @@ int main(int argc, char **argv, char **envp)
TFR(fd = open("/dev/null", O_RDWR)); TFR(fd = open("/dev/null", O_RDWR));
if (fd == -1) if (fd == -1)
exit(1); exit(1);
}
dup2(fd, 0); #ifndef _WIN32
dup2(fd, 1); if (run_as) {
dup2(fd, 2); pwd = getpwnam(run_as);
if (!pwd) {
fprintf(stderr, "User \"%s\" doesn't exist\n", run_as);
exit(1);
}
}
if (chroot_dir) {
if (chroot(chroot_dir) < 0) {
fprintf(stderr, "chroot failed\n");
exit(1);
}
chdir("/");
}
if (run_as) {
if (setgid(pwd->pw_gid) < 0) {
fprintf(stderr, "Failed to setgid(%d)\n", pwd->pw_gid);
exit(1);
}
if (setuid(pwd->pw_uid) < 0) {
fprintf(stderr, "Failed to setuid(%d)\n", pwd->pw_uid);
exit(1);
}
if (setuid(0) != -1) {
fprintf(stderr, "Dropping privileges failed\n");
exit(1);
}
}
#endif
if (daemonize) {
dup2(fd, 0);
dup2(fd, 1);
dup2(fd, 2);
close(fd); close(fd);
} }
main_loop(); main_loop();
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册