X-Git-Url: https://www.chiark.greenend.org.uk/ucgi/~ianmdlvl/git?a=blobdiff_plain;f=src%2Fnspawn%2Fnspawn.c;h=dd7337bc91351e80632fb57fdad84ab0d5986d2f;hb=9bd37b40fac198fee2ff4eabc8793f1a7f2770fe;hp=06d627c0a9ce1840c938af070385073a292c7080;hpb=5b30bef856e89a571df57b7b953e9a1409d9aced;p=elogind.git diff --git a/src/nspawn/nspawn.c b/src/nspawn/nspawn.c index 06d627c0a..dd7337bc9 100644 --- a/src/nspawn/nspawn.c +++ b/src/nspawn/nspawn.c @@ -61,6 +61,7 @@ #include "bus-util.h" #include "bus-error.h" #include "ptyfwd.h" +#include "bus-kernel.h" #ifndef TTY_GID #define TTY_GID 5 @@ -127,6 +128,7 @@ static int help(void) { " --read-only Mount the root directory read-only\n" " --capability=CAP In addition to the default, retain specified\n" " capability\n" + " --drop-capability=CAP Drop the specified capability from the default set\n" " --link-journal=MODE Link up guest journal, one of no, auto, guest, host\n" " -j Equivalent to --link-journal=host\n" " --bind=PATH[:PATH] Bind mount a file or directory from the host into\n" @@ -145,6 +147,7 @@ static int parse_argv(int argc, char *argv[]) { ARG_UUID, ARG_READ_ONLY, ARG_CAPABILITY, + ARG_DROP_CAPABILITY, ARG_LINK_JOURNAL, ARG_BIND, ARG_BIND_RO @@ -160,6 +163,7 @@ static int parse_argv(int argc, char *argv[]) { { "uuid", required_argument, NULL, ARG_UUID }, { "read-only", no_argument, NULL, ARG_READ_ONLY }, { "capability", required_argument, NULL, ARG_CAPABILITY }, + { "drop-capability", required_argument, NULL, ARG_DROP_CAPABILITY }, { "link-journal", required_argument, NULL, ARG_LINK_JOURNAL }, { "bind", required_argument, NULL, ARG_BIND }, { "bind-ro", required_argument, NULL, ARG_BIND_RO }, @@ -189,7 +193,7 @@ static int parse_argv(int argc, char *argv[]) { free(arg_directory); arg_directory = canonicalize_file_name(optarg); if (!arg_directory) { - log_error("Failed to canonicalize root directory."); + log_error("Invalid root directory: %m"); return -ENOMEM; } @@ -243,7 +247,8 @@ static int parse_argv(int argc, char *argv[]) { arg_read_only = true; break; - case ARG_CAPABILITY: { + case ARG_CAPABILITY: + case ARG_DROP_CAPABILITY: { char *state, *word; size_t length; @@ -262,7 +267,11 @@ static int parse_argv(int argc, char *argv[]) { } free(t); - arg_retain |= 1ULL << (uint64_t) cap; + + if (c == ARG_CAPABILITY) + arg_retain |= 1ULL << (uint64_t) cap; + else + arg_retain &= ~(1ULL << (uint64_t) cap); } break; @@ -919,6 +928,26 @@ static int setup_journal(const char *directory) { return 0; } +static int setup_kdbus(const char *dest, const char *path) { + const char *p; + + if (!path) + return 0; + + p = strappenda(dest, "/dev/kdbus"); + if (mkdir(p, 0755) < 0) { + log_error("Failed to create kdbus path: %m"); + return -errno; + } + + if (mount(path, p, "bind", MS_BIND, NULL) < 0) { + log_error("Failed to mount kdbus namespace path: %m"); + return -errno; + } + + return 0; +} + static int drop_capabilities(void) { return capability_bounding_set_drop(~arg_retain, false); } @@ -965,7 +994,7 @@ static int terminate_machine(pid_t pid) { const char *path; int r; - r = sd_bus_open_system(&bus); + r = sd_bus_default_system(&bus); if (r < 0) { log_error("Failed to open system bus: %s", strerror(-r)); return r; @@ -1024,12 +1053,13 @@ static bool audit_enabled(void) { int main(int argc, char *argv[]) { pid_t pid = 0; int r = EXIT_FAILURE, k; - _cleanup_close_ int master = -1; + _cleanup_close_ int master = -1, kdbus_fd = -1; int n_fd_passed; const char *console = NULL; sigset_t mask; _cleanup_close_pipe_ int kmsg_socket_pair[2] = { -1, -1 }; _cleanup_fdset_free_ FDSet *fds = NULL; + _cleanup_free_ char *kdbus_namespace = NULL; log_parse_environment(); log_open(); @@ -1130,6 +1160,12 @@ int main(int argc, char *argv[]) { goto finish; } + kdbus_fd = bus_kernel_create_namespace(arg_machine, &kdbus_namespace); + if (r < 0) + log_debug("Failed to create kdbus namespace: %s", strerror(-r)); + else + log_debug("Successfully created kdbus namespace as %s", kdbus_namespace); + if (socketpair(AF_UNIX, SOCK_DGRAM|SOCK_NONBLOCK|SOCK_CLOEXEC, 0, kmsg_socket_pair) < 0) { log_error("Failed to create kmsg socket pair."); goto finish; @@ -1281,6 +1317,9 @@ int main(int argc, char *argv[]) { if (mount_binds(arg_directory, arg_bind_ro, MS_RDONLY) < 0) goto child_fail; + if (setup_kdbus(arg_directory, kdbus_namespace) < 0) + goto child_fail; + if (chdir(arg_directory) < 0) { log_error("chdir(%s) failed: %m", arg_directory); goto child_fail;