]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
inaccessible: move inaccessible file nodes to /systemd/ subdir in runtime dir always 16118/head
authorLennart Poettering <lennart@poettering.net>
Tue, 9 Jun 2020 14:22:24 +0000 (16:22 +0200)
committerLennart Poettering <lennart@poettering.net>
Tue, 9 Jun 2020 14:23:56 +0000 (16:23 +0200)
Let's make sure $XDG_RUNTIME_DIR for the user instance and /run for the
system instance is always organized the same way: the "inaccessible"
device nodes should be placed in a subdir of either called "systemd" and
a subdir of that called "inaccessible".

This way we can emphasize the common behaviour, and only differ where
really necessary.

Follow-up for #13823

src/core/mount-setup.c
src/core/namespace.c
src/nspawn/nspawn-mount.c
src/nspawn/nspawn.c
src/shared/dev-setup.c
src/shared/mount-util.c
src/test/test-dev-setup.c

index dd44d5eb9203d2e4d727c592b3d27d7f66c86c77..028c4de2802ba827ddb01f1651a9a9c8d726f0d9 100644 (file)
@@ -535,9 +535,9 @@ int mount_setup(bool loaded_policy, bool leave_propagation) {
         (void) mkdir_label("/run/systemd", 0755);
         (void) mkdir_label("/run/systemd/system", 0755);
 
-        /* Also create /run/systemd/inaccessible nodes, so that we always have something to mount inaccessible nodes
-         * from. */
-        (void) make_inaccessible_nodes("/run/systemd", UID_INVALID, GID_INVALID);
+        /* Also create /run/systemd/inaccessible nodes, so that we always have something to mount
+         * inaccessible nodes from. */
+        (void) make_inaccessible_nodes(NULL, UID_INVALID, GID_INVALID);
 
         return 0;
 }
index 34eb469fb825990d84a2c704fd451cea13dc4e02..9bea6ea46c816c77a2d945f731737102bbaacb50 100644 (file)
@@ -939,10 +939,10 @@ static int apply_mount(
                 }
 
                 if (geteuid() == 0)
-                        runtime_dir = "/run/systemd";
+                        runtime_dir = "/run";
                 else {
-                        if (asprintf(&tmp, "/run/user/"UID_FMT, geteuid()) < 0)
-                                log_oom();
+                        if (asprintf(&tmp, "/run/user/" UID_FMT, geteuid()) < 0)
+                                return -ENOMEM;
 
                         runtime_dir = tmp;
                 }
index 33cc19a4251510f9db59d81a012221fb7cc27b67..eb80c2960bd34da907834d52d9f465d6905a050a 100644 (file)
@@ -898,7 +898,7 @@ static int mount_inaccessible(const char *dest, CustomMount *m) {
                 return m->graceful ? 0 : r;
         }
 
-        r = mode_to_inaccessible_node("/run/systemd", st.st_mode, &source);
+        r = mode_to_inaccessible_node(NULL, st.st_mode, &source);
         if (r < 0)
                 return m->graceful ? 0 : r;
 
index 8e8881749aa54f56cf21936c8767a80556b65f9b..0ce71e1103fd1d134f513d5abc061a27bd58e3a3 100644 (file)
@@ -3471,7 +3471,7 @@ static int outer_child(
 
         (void) dev_setup(directory, arg_uid_shift, arg_uid_shift);
 
-        p = prefix_roota(directory, "/run/systemd");
+        p = prefix_roota(directory, "/run");
         (void) make_inaccessible_nodes(p, arg_uid_shift, arg_uid_shift);
 
         r = setup_pts(directory);
index 4bce8b167b551c9b64852d669d6be8660ccd1bac..6a280cde016341b95996f4eda2166b79e790527b 100644 (file)
@@ -56,31 +56,38 @@ int dev_setup(const char *prefix, uid_t uid, gid_t gid) {
         return 0;
 }
 
-int make_inaccessible_nodes(const char *root, uid_t uid, gid_t gid) {
+int make_inaccessible_nodes(
+                const char *runtime_dir,
+                uid_t uid,
+                gid_t gid) {
+
         static const struct {
                 const char *name;
                 mode_t mode;
         } table[] = {
-                { "",                   S_IFDIR  | 0755 },
-                { "/inaccessible",      S_IFDIR  | 0000 },
-                { "/inaccessible/reg",  S_IFREG  | 0000 },
-                { "/inaccessible/dir",  S_IFDIR  | 0000 },
-                { "/inaccessible/fifo", S_IFIFO  | 0000 },
-                { "/inaccessible/sock", S_IFSOCK | 0000 },
+                { "/systemd",                   S_IFDIR  | 0755 },
+                { "/systemd/inaccessible",      S_IFDIR  | 0000 },
+                { "/systemd/inaccessible/reg",  S_IFREG  | 0000 },
+                { "/systemd/inaccessible/dir",  S_IFDIR  | 0000 },
+                { "/systemd/inaccessible/fifo", S_IFIFO  | 0000 },
+                { "/systemd/inaccessible/sock", S_IFSOCK | 0000 },
 
                 /* The following two are likely to fail if we lack the privs for it (for example in an userns
                  * environment, if CAP_SYS_MKNOD is missing, or if a device node policy prohibit major/minor of 0
                  * device nodes to be created). But that's entirely fine. Consumers of these files should carry
                  * fallback to use a different node then, for example <root>/inaccessible/sock, which is close
                  * enough in behaviour and semantics for most uses. */
-                { "/inaccessible/chr",  S_IFCHR  | 0000 },
-                { "/inaccessible/blk",  S_IFBLK  | 0000 },
+                { "/systemd/inaccessible/chr",  S_IFCHR  | 0000 },
+                { "/systemd/inaccessible/blk",  S_IFBLK  | 0000 },
         };
 
         _cleanup_umask_ mode_t u;
         size_t i;
         int r;
 
+        if (!runtime_dir)
+                runtime_dir = "/run";
+
         u = umask(0000);
 
         /* Set up inaccessible (and empty) file nodes of all types. This are used to as mount sources for over-mounting
@@ -91,7 +98,7 @@ int make_inaccessible_nodes(const char *root, uid_t uid, gid_t gid) {
         for (i = 0; i < ELEMENTSOF(table); i++) {
                 _cleanup_free_ char *path = NULL;
 
-                path = path_join(root, table[i].name);
+                path = path_join(runtime_dir, table[i].name);
                 if (!path)
                         return log_oom();
 
index f3ee656c0f179374262638f06882f9770132c1f2..d188e6bd7f63dea62fec2f2bc476b587bb4cd4cd 100644 (file)
@@ -397,71 +397,73 @@ int repeat_unmount(const char *path, int flags) {
         }
 }
 
-int mode_to_inaccessible_node(const char *runtime_dir, mode_t mode, char **dest) {
-        /* This function maps a node type to a corresponding inaccessible file node. These nodes are created during
-         * early boot by PID 1. In some cases we lacked the privs to create the character and block devices (maybe
-         * because we run in an userns environment, or miss CAP_SYS_MKNOD, or run with a devices policy that excludes
-         * device nodes with major and minor of 0), but that's fine, in that case we use an AF_UNIX file node instead,
-         * which is not the same, but close enough for most uses. And most importantly, the kernel allows bind mounts
-         * from socket nodes to any non-directory file nodes, and that's the most important thing that matters. */
+int mode_to_inaccessible_node(
+                const char *runtime_dir,
+                mode_t mode,
+                char **ret) {
+
+        /* This function maps a node type to a corresponding inaccessible file node. These nodes are created
+         * during early boot by PID 1. In some cases we lacked the privs to create the character and block
+         * devices (maybe because we run in an userns environment, or miss CAP_SYS_MKNOD, or run with a
+         * devices policy that excludes device nodes with major and minor of 0), but that's fine, in that
+         * case we use an AF_UNIX file node instead, which is not the same, but close enough for most
+         * uses. And most importantly, the kernel allows bind mounts from socket nodes to any non-directory
+         * file nodes, and that's the most important thing that matters.
+         *
+         * Note that the runtime directory argument shall be the top-level runtime directory, i.e. /run/ if
+         * we operate in system context and $XDG_RUNTIME_DIR if we operate in user context. */
+
         _cleanup_free_ char *d = NULL;
         const char *node = NULL;
-        char *tmp;
+        bool fallback = false;
 
-        assert(dest);
+        assert(ret);
+
+        if (!runtime_dir)
+                runtime_dir = "/run";
 
         switch(mode & S_IFMT) {
                 case S_IFREG:
-                        node = "/inaccessible/reg";
+                        node = "/systemd/inaccessible/reg";
                         break;
 
                 case S_IFDIR:
-                        node = "/inaccessible/dir";
+                        node = "/systemd/inaccessible/dir";
                         break;
 
                 case S_IFCHR:
-                        d = path_join(runtime_dir, "/inaccessible/chr");
-                        if (!d)
-                                return log_oom();
-
-                        if (access(d, F_OK) == 0) {
-                                *dest = TAKE_PTR(d);
-                                return 0;
-                        }
-
-                        node = "/inaccessible/sock";
+                        node = "/systemd/inaccessible/chr";
+                        fallback = true;
                         break;
 
                 case S_IFBLK:
-                        d = path_join(runtime_dir, "/inaccessible/blk");
-                        if (!d)
-                                return log_oom();
-
-                        if (access(d, F_OK) == 0) {
-                                *dest = TAKE_PTR(d);
-                                return 0;
-                        }
-
-                        node = "/inaccessible/sock";
+                        node = "/systemd/inaccessible/blk";
+                        fallback = true;
                         break;
 
                 case S_IFIFO:
-                        node = "/inaccessible/fifo";
+                        node = "/systemd/inaccessible/fifo";
                         break;
 
                 case S_IFSOCK:
-                        node = "/inaccessible/sock";
+                        node = "/systemd/inaccessible/sock";
                         break;
         }
-
         if (!node)
                 return -EINVAL;
 
-        tmp = path_join(runtime_dir, node);
-        if (!tmp)
-                return log_oom();
+        d = path_join(runtime_dir, node);
+        if (!d)
+                return -ENOMEM;
+
+        if (fallback && access(d, F_OK) < 0) {
+                free(d);
+                d = path_join(runtime_dir, "/systemd/inaccessible/sock");
+                if (!d)
+                        return -ENOMEM;
+        }
 
-        *dest = tmp;
+        *ret = TAKE_PTR(d);
         return 0;
 }
 
index d991fe52004df26415cb2891d90604fbfa1c8897..038484e475971821df3ccbafd0eea41b602ba731 100644 (file)
@@ -20,7 +20,6 @@ int main(int argc, char *argv[]) {
         f = prefix_roota(p, "/run");
         assert_se(mkdir(f, 0755) >= 0);
 
-        f = prefix_roota(p, "/run/systemd");
         assert_se(make_inaccessible_nodes(f, 1, 1) >= 0);
 
         f = prefix_roota(p, "/run/systemd/inaccessible/reg");