summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLennart Poettering <lennart@poettering.net>2020-06-09 16:22:24 +0200
committerLennart Poettering <lennart@poettering.net>2020-06-09 16:23:56 +0200
commit48b747fa03ec6b7edd7a31621c5b1d6cf123283d (patch)
tree701083f3f1883e2f55bcb47f94033db8c0b46f72
parentb8c90745349e18ec0bd0a7d2affb139400d8777a (diff)
downloadsystemd-48b747fa03ec6b7edd7a31621c5b1d6cf123283d.tar.gz
inaccessible: move inaccessible file nodes to /systemd/ subdir in runtime dir always
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
-rw-r--r--src/core/mount-setup.c6
-rw-r--r--src/core/namespace.c6
-rw-r--r--src/nspawn/nspawn-mount.c2
-rw-r--r--src/nspawn/nspawn.c2
-rw-r--r--src/shared/dev-setup.c27
-rw-r--r--src/shared/mount-util.c78
-rw-r--r--src/test/test-dev-setup.c1
7 files changed, 65 insertions, 57 deletions
diff --git a/src/core/mount-setup.c b/src/core/mount-setup.c
index dd44d5eb92..028c4de280 100644
--- a/src/core/mount-setup.c
+++ b/src/core/mount-setup.c
@@ -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;
}
diff --git a/src/core/namespace.c b/src/core/namespace.c
index 34eb469fb8..9bea6ea46c 100644
--- a/src/core/namespace.c
+++ b/src/core/namespace.c
@@ -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;
}
diff --git a/src/nspawn/nspawn-mount.c b/src/nspawn/nspawn-mount.c
index 33cc19a425..eb80c2960b 100644
--- a/src/nspawn/nspawn-mount.c
+++ b/src/nspawn/nspawn-mount.c
@@ -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;
diff --git a/src/nspawn/nspawn.c b/src/nspawn/nspawn.c
index 8e8881749a..0ce71e1103 100644
--- a/src/nspawn/nspawn.c
+++ b/src/nspawn/nspawn.c
@@ -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);
diff --git a/src/shared/dev-setup.c b/src/shared/dev-setup.c
index 4bce8b167b..6a280cde01 100644
--- a/src/shared/dev-setup.c
+++ b/src/shared/dev-setup.c
@@ -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();
diff --git a/src/shared/mount-util.c b/src/shared/mount-util.c
index f3ee656c0f..d188e6bd7f 100644
--- a/src/shared/mount-util.c
+++ b/src/shared/mount-util.c
@@ -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;
}
diff --git a/src/test/test-dev-setup.c b/src/test/test-dev-setup.c
index d991fe5200..038484e475 100644
--- a/src/test/test-dev-setup.c
+++ b/src/test/test-dev-setup.c
@@ -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");