summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLennart Poettering <lennart@poettering.net>2020-04-22 16:35:32 +0200
committerZbigniew Jędrzejewski-Szmek <zbyszek@in.waw.pl>2020-04-28 19:40:46 +0200
commitdcff2fa5d16f01edd774cd9dbc21fa4385af65bb (patch)
tree63a929203b3cc284e037b1cd9a5c24b00e095f01
parentc98fef264b4834955e4fe3dd9b4bc76f370888af (diff)
downloadsystemd-dcff2fa5d16f01edd774cd9dbc21fa4385af65bb.tar.gz
nspawn: be more careful with creating/chowning directories to overmount
We should never re-chown selinuxfs. Fixes: #15475
-rw-r--r--src/nspawn/nspawn-mount.c40
-rw-r--r--src/nspawn/nspawn-mount.h1
2 files changed, 22 insertions, 19 deletions
diff --git a/src/nspawn/nspawn-mount.c b/src/nspawn/nspawn-mount.c
index a862355a64..59bd73d2ea 100644
--- a/src/nspawn/nspawn-mount.c
+++ b/src/nspawn/nspawn-mount.c
@@ -569,7 +569,7 @@ int mount_all(const char *dest,
static const MountPoint mount_table[] = {
/* First we list inner child mounts (i.e. mounts applied *after* entering user namespacing) */
{ "proc", "/proc", "proc", NULL, MS_NOSUID|MS_NOEXEC|MS_NODEV,
- MOUNT_FATAL|MOUNT_IN_USERNS },
+ MOUNT_FATAL|MOUNT_IN_USERNS|MOUNT_MKDIR },
{ "/proc/sys", "/proc/sys", NULL, NULL, MS_BIND,
MOUNT_FATAL|MOUNT_IN_USERNS|MOUNT_APPLY_APIVFS_RO }, /* Bind mount first ... */
@@ -599,23 +599,23 @@ int mount_all(const char *dest,
PROC_READ_ONLY("/proc/scsi"),
{ "mqueue", "/dev/mqueue", "mqueue", NULL, MS_NOSUID|MS_NOEXEC|MS_NODEV,
- MOUNT_IN_USERNS },
+ MOUNT_IN_USERNS|MOUNT_MKDIR },
/* Then we list outer child mounts (i.e. mounts applied *before* entering user namespacing) */
{ "tmpfs", "/tmp", "tmpfs", "mode=1777", MS_NOSUID|MS_NODEV|MS_STRICTATIME,
- MOUNT_FATAL|MOUNT_APPLY_TMPFS_TMP },
+ MOUNT_FATAL|MOUNT_APPLY_TMPFS_TMP|MOUNT_MKDIR },
{ "tmpfs", "/sys", "tmpfs", "mode=555", MS_NOSUID|MS_NOEXEC|MS_NODEV,
- MOUNT_FATAL|MOUNT_APPLY_APIVFS_NETNS },
+ MOUNT_FATAL|MOUNT_APPLY_APIVFS_NETNS|MOUNT_MKDIR },
{ "sysfs", "/sys", "sysfs", NULL, MS_RDONLY|MS_NOSUID|MS_NOEXEC|MS_NODEV,
- MOUNT_FATAL|MOUNT_APPLY_APIVFS_RO }, /* skipped if above was mounted */
+ MOUNT_FATAL|MOUNT_APPLY_APIVFS_RO|MOUNT_MKDIR }, /* skipped if above was mounted */
{ "sysfs", "/sys", "sysfs", NULL, MS_NOSUID|MS_NOEXEC|MS_NODEV,
- MOUNT_FATAL }, /* skipped if above was mounted */
+ MOUNT_FATAL|MOUNT_MKDIR }, /* skipped if above was mounted */
{ "tmpfs", "/dev", "tmpfs", "mode=755", MS_NOSUID|MS_STRICTATIME,
- MOUNT_FATAL },
+ MOUNT_FATAL|MOUNT_MKDIR },
{ "tmpfs", "/dev/shm", "tmpfs", "mode=1777", MS_NOSUID|MS_NODEV|MS_STRICTATIME,
- MOUNT_FATAL },
+ MOUNT_FATAL|MOUNT_MKDIR },
{ "tmpfs", "/run", "tmpfs", "mode=755", MS_NOSUID|MS_NODEV|MS_STRICTATIME,
- MOUNT_FATAL },
+ MOUNT_FATAL|MOUNT_MKDIR },
#if HAVE_SELINUX
{ "/sys/fs/selinux", "/sys/fs/selinux", NULL, NULL, MS_BIND,
@@ -663,17 +663,19 @@ int mount_all(const char *dest,
continue;
}
- r = mkdir_userns_p(dest, where, 0755, (use_userns && !in_userns) ? uid_shift : UID_INVALID);
- if (r < 0 && r != -EEXIST) {
- if (fatal && r != -EROFS)
- return log_error_errno(r, "Failed to create directory %s: %m", where);
+ if (FLAGS_SET(mount_table[k].mount_settings, MOUNT_MKDIR)) {
+ r = mkdir_userns_p(dest, where, 0755, (use_userns && !in_userns) ? uid_shift : UID_INVALID);
+ if (r < 0 && r != -EEXIST) {
+ if (fatal && r != -EROFS)
+ return log_error_errno(r, "Failed to create directory %s: %m", where);
- log_debug_errno(r, "Failed to create directory %s: %m", where);
- /* If we failed mkdir() or chown() due to the root
- * directory being read only, attempt to mount this fs
- * anyway and let mount_verbose log any errors */
- if (r != -EROFS)
- continue;
+ log_debug_errno(r, "Failed to create directory %s: %m", where);
+
+ /* If we failed mkdir() or chown() due to the root directory being read only,
+ * attempt to mount this fs anyway and let mount_verbose log any errors */
+ if (r != -EROFS)
+ continue;
+ }
}
o = mount_table[k].options;
diff --git a/src/nspawn/nspawn-mount.h b/src/nspawn/nspawn-mount.h
index 680ff350e5..e8bb903839 100644
--- a/src/nspawn/nspawn-mount.h
+++ b/src/nspawn/nspawn-mount.h
@@ -16,6 +16,7 @@ typedef enum MountSettingsMask {
MOUNT_APPLY_TMPFS_TMP = 1 << 5, /* if set, /tmp will be mounted as tmpfs */
MOUNT_ROOT_ONLY = 1 << 6, /* if set, only root mounts are mounted */
MOUNT_NON_ROOT_ONLY = 1 << 7, /* if set, only non-root mounts are mounted */
+ MOUNT_MKDIR = 1 << 8, /* if set, make directory to mount over first */
} MountSettingsMask;
typedef enum CustomMountType {