]> git.ipfire.org Git - thirdparty/systemd.git/blobdiff - src/core/namespace.c
util-lib: split our string related calls from util.[ch] into its own file string...
[thirdparty/systemd.git] / src / core / namespace.c
index 5b782798c89ff3b0bf1264c9b947f59469d1c5b1..6806fc27e6c8813921aa282b3e4ee99cada627a0 100644 (file)
 ***/
 
 #include <errno.h>
-#include <sys/mount.h>
-#include <string.h>
+#include <sched.h>
 #include <stdio.h>
-#include <unistd.h>
+#include <string.h>
+#include <sys/mount.h>
 #include <sys/stat.h>
-#include <sched.h>
+#include <unistd.h>
 #include <linux/fs.h>
 
-#include "strv.h"
-#include "util.h"
-#include "path-util.h"
-#include "missing.h"
-#include "loopback-setup.h"
 #include "dev-setup.h"
+#include "loopback-setup.h"
+#include "missing.h"
+#include "mkdir.h"
+#include "path-util.h"
 #include "selinux-util.h"
+#include "string-util.h"
+#include "strv.h"
+#include "util.h"
 #include "namespace.h"
-#include "mkdir.h"
 
 typedef enum MountMode {
         /* This is ordered by priority! */
@@ -125,22 +126,6 @@ static void drop_duplicates(BindMount *m, unsigned *n) {
         *n = t - m;
 }
 
-static int mount_move_root(const char *path) {
-        if (chdir(path) < 0)
-                return -errno;
-
-        if (mount(path, "/", NULL, MS_MOVE, NULL) < 0)
-                return -errno;
-
-        if (chroot(".") < 0)
-                return -errno;
-
-        if (chdir("/") < 0)
-                return -errno;
-
-        return 0;
-}
-
 static int mount_dev(BindMount *m) {
         static const char devnodes[] =
                 "/dev/null\0"
@@ -240,7 +225,7 @@ static int mount_dev(BindMount *m) {
                 }
         }
 
-        dev_setup(temporary_mount);
+        dev_setup(temporary_mount, UID_INVALID, GID_INVALID);
 
         /* Create the /dev directory if missing. It is more likely to be
          * missing when the service is started with RootDirectory. This is
@@ -304,22 +289,21 @@ static int mount_kdbus(BindMount *m) {
         /* create a new /dev/null dev node copy so we have some fodder to
          * bind-mount the custom endpoint over. */
         if (stat("/dev/null", &st) < 0) {
-                log_error_errno(errno, "Failed to stat /dev/null: %m");
-                r = -errno;
+                r = log_error_errno(errno, "Failed to stat /dev/null: %m");
                 goto fail;
         }
 
         busnode = strjoina(root, "/bus");
         if (mknod(busnode, (st.st_mode & ~07777) | 0600, st.st_rdev) < 0) {
-                log_error_errno(errno, "mknod() for %s failed: %m", busnode);
-                r = -errno;
+                r = log_error_errno(errno, "mknod() for %s failed: %m",
+                                    busnode);
                 goto fail;
         }
 
         r = mount(m->path, busnode, NULL, MS_BIND, NULL);
         if (r < 0) {
-                log_error_errno(errno, "bind mount of %s failed: %m", m->path);
-                r = -errno;
+                r = log_error_errno(errno, "bind mount of %s failed: %m",
+                                    m->path);
                 goto fail;
         }
 
@@ -330,8 +314,8 @@ static int mount_kdbus(BindMount *m) {
         }
 
         if (mount(root, basepath, NULL, MS_MOVE, NULL) < 0) {
-                log_error_errno(errno, "bind mount of %s failed: %m", basepath);
-                r = -errno;
+                r = log_error_errno(errno, "bind mount of %s failed: %m",
+                                    basepath);
                 goto fail;
         }
 
@@ -515,7 +499,7 @@ int setup_namespace(
                 if (protect_system != PROTECT_SYSTEM_NO) {
                         const char *usr_dir, *boot_dir, *etc_dir;
 
-                        usr_dir = prefix_roota(root_directory, "/home");
+                        usr_dir = prefix_roota(root_directory, "/usr");
                         boot_dir = prefix_roota(root_directory, "/boot");
                         boot_dir = strjoina("-", boot_dir);
                         etc_dir = prefix_roota(root_directory, "/etc");
@@ -572,10 +556,9 @@ int setup_namespace(
         /* Remount / as the desired mode. Not that this will not
          * reestablish propagation from our side to the host, since
          * what's disconnected is disconnected. */
-        if (mount(NULL, "/", NULL, mount_flags | MS_REC, NULL) < 0) {
+        if (mount(NULL, "/", NULL, mount_flags | MS_REC, NULL) < 0)
                 /* at this point, we cannot rollback */
                 return -errno;
-        }
 
         return 0;
 
@@ -661,16 +644,7 @@ int setup_tmp_dirs(const char *id, char **tmp_dir, char **var_tmp_dir) {
 
 int setup_netns(int netns_storage_socket[2]) {
         _cleanup_close_ int netns = -1;
-        union {
-                struct cmsghdr cmsghdr;
-                uint8_t buf[CMSG_SPACE(sizeof(int))];
-        } control = {};
-        struct msghdr mh = {
-                .msg_control = &control,
-                .msg_controllen = sizeof(control),
-        };
-        struct cmsghdr *cmsg;
-        int r;
+        int r, q;
 
         assert(netns_storage_socket);
         assert(netns_storage_socket[0] >= 0);
@@ -687,12 +661,8 @@ int setup_netns(int netns_storage_socket[2]) {
         if (lockf(netns_storage_socket[0], F_LOCK, 0) < 0)
                 return -errno;
 
-        if (recvmsg(netns_storage_socket[0], &mh, MSG_DONTWAIT|MSG_CMSG_CLOEXEC) < 0) {
-                if (errno != EAGAIN) {
-                        r = -errno;
-                        goto fail;
-                }
-
+        netns = receive_one_fd(netns_storage_socket[0], MSG_DONTWAIT);
+        if (netns == -EAGAIN) {
                 /* Nothing stored yet, so let's create a new namespace */
 
                 if (unshare(CLONE_NEWNET) < 0) {
@@ -709,16 +679,13 @@ int setup_netns(int netns_storage_socket[2]) {
                 }
 
                 r = 1;
-        } else {
-                /* Yay, found something, so let's join the namespace */
 
-                for (cmsg = CMSG_FIRSTHDR(&mh); cmsg; cmsg = CMSG_NXTHDR(&mh, cmsg)) {
-                        if (cmsg->cmsg_level == SOL_SOCKET && cmsg->cmsg_type == SCM_RIGHTS) {
-                                assert(cmsg->cmsg_len == CMSG_LEN(sizeof(int)));
-                                netns = *(int*) CMSG_DATA(cmsg);
-                        }
-                }
+        } else if (netns < 0) {
+                r = netns;
+                goto fail;
 
+        } else {
+                /* Yay, found something, so let's join the namespace */
                 if (setns(netns, CLONE_NEWNET) < 0) {
                         r = -errno;
                         goto fail;
@@ -727,21 +694,14 @@ int setup_netns(int netns_storage_socket[2]) {
                 r = 0;
         }
 
-        cmsg = CMSG_FIRSTHDR(&mh);
-        cmsg->cmsg_level = SOL_SOCKET;
-        cmsg->cmsg_type = SCM_RIGHTS;
-        cmsg->cmsg_len = CMSG_LEN(sizeof(int));
-        memcpy(CMSG_DATA(cmsg), &netns, sizeof(int));
-        mh.msg_controllen = cmsg->cmsg_len;
-
-        if (sendmsg(netns_storage_socket[1], &mh, MSG_DONTWAIT|MSG_NOSIGNAL) < 0) {
-                r = -errno;
+        q = send_one_fd(netns_storage_socket[1], netns, MSG_DONTWAIT);
+        if (q < 0) {
+                r = q;
                 goto fail;
         }
 
 fail:
         lockf(netns_storage_socket[0], F_ULOCK, 0);
-
         return r;
 }