[systemd-commits] src/nspawn

Lennart Poettering lennart at kemper.freedesktop.org
Wed Jan 8 16:47:43 PST 2014


 src/nspawn/nspawn.c |   32 ++++++++++++++++++++++++--------
 1 file changed, 24 insertions(+), 8 deletions(-)

New commits:
commit 354bfd2b166d1044eea05ac9ba1cda05c93a24bc
Author: Lennart Poettering <lennart at poettering.net>
Date:   Thu Jan 9 08:42:57 2014 +0800

    nspawn: do not invoke RegisterMachine on machined from inside the new PID namespace
    
    On kdbus user credentials are not translated across PID namespaces, but
    simply invalidated if sender and receiver namespaces don't match. This
    makes it impossible to properly authenticate requests from different PID
    namespaces (which is probably a good thing). Hence, register the machine
    in the parent and not the client and properly synchronize this.

diff --git a/src/nspawn/nspawn.c b/src/nspawn/nspawn.c
index 241b4b5..caf1aa9 100644
--- a/src/nspawn/nspawn.c
+++ b/src/nspawn/nspawn.c
@@ -40,6 +40,7 @@
 #include <sys/un.h>
 #include <sys/socket.h>
 #include <linux/netlink.h>
+#include <sys/eventfd.h>
 
 #include "sd-daemon.h"
 #include "sd-bus.h"
@@ -996,7 +997,7 @@ static int drop_capabilities(void) {
         return capability_bounding_set_drop(~arg_retain, false);
 }
 
-static int register_machine(void) {
+static int register_machine(pid_t pid) {
         _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
         _cleanup_bus_unref_ sd_bus *bus = NULL;
         int r;
@@ -1020,7 +1021,7 @@ static int register_machine(void) {
                         SD_BUS_MESSAGE_APPEND_ID128(arg_uuid),
                         "nspawn",
                         "container",
-                        (uint32_t) 0,
+                        (uint32_t) pid,
                         strempty(arg_directory),
                         !isempty(arg_slice), "Slice", "s", arg_slice);
         if (r < 0) {
@@ -1097,7 +1098,7 @@ 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, kdbus_fd = -1;
+        _cleanup_close_ int master = -1, kdbus_fd = -1, sync_fd = -1;
         int n_fd_passed;
         const char *console = NULL;
         sigset_t mask;
@@ -1213,7 +1214,13 @@ int main(int argc, char *argv[]) {
                 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.");
+                log_error("Failed to create kmsg socket pair: %m");
+                goto finish;
+        }
+
+        sync_fd = eventfd(0, EFD_CLOEXEC);
+        if (sync_fd < 0) {
+                log_error("Failed to create event fd: %m");
                 goto finish;
         }
 
@@ -1255,6 +1262,7 @@ int main(int argc, char *argv[]) {
                                 NULL
                         };
                         char **env_use;
+                        eventfd_t x;
 
                         envp[n_env] = strv_find_prefix(environ, "TERM=");
                         if (envp[n_env])
@@ -1302,10 +1310,6 @@ int main(int argc, char *argv[]) {
                                 goto child_fail;
                         }
 
-                        r = register_machine();
-                        if (r < 0)
-                                goto finish;
-
                         /* Mark everything as slave, so that we still
                          * receive mounts from the real root, but don't
                          * propagate mounts to the real root. */
@@ -1482,6 +1486,10 @@ int main(int argc, char *argv[]) {
 
                         setup_hostname();
 
+                        eventfd_read(sync_fd, &x);
+                        close_nointr_nofail(sync_fd);
+                        sync_fd = -1;
+
                         if (!strv_isempty(arg_setenv)) {
                                 char **n;
 
@@ -1529,6 +1537,14 @@ int main(int argc, char *argv[]) {
                 fdset_free(fds);
                 fds = NULL;
 
+                r = register_machine(pid);
+                if (r < 0)
+                        goto finish;
+
+                eventfd_write(sync_fd, 1);
+                close_nointr_nofail(sync_fd);
+                sync_fd = -1;
+
                 k = process_pty(master, &mask, arg_boot ? pid : 0, SIGRTMIN+3);
                 if (k < 0) {
                         r = EXIT_FAILURE;



More information about the systemd-commits mailing list