]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
mount-util: switch most mount_verbose() code over to not follow symlinks
authorLennart Poettering <lennart@poettering.net>
Tue, 22 Sep 2020 13:51:17 +0000 (15:51 +0200)
committerLennart Poettering <lennart@poettering.net>
Wed, 23 Sep 2020 16:57:36 +0000 (18:57 +0200)
14 files changed:
src/core/automount.c
src/home/homework-directory.c
src/home/homework-luks.c
src/home/homework-mount.c
src/nspawn/nspawn-cgroup.c
src/nspawn/nspawn-mount.c
src/nspawn/nspawn-mount.h
src/nspawn/nspawn.c
src/partition/repart.c
src/shared/dissect-image.c
src/shared/mount-util.c
src/shared/mount-util.h
src/test/test-udev.c
src/volatile-root/volatile-root.c

index 4db763f84ecfd88a5a29dc8b68dbcc791f0e3a2f..8318deef8a0e1ad2acb7c539c97da0e1121ecbfd 100644 (file)
@@ -601,10 +601,9 @@ static void automount_enter_waiting(Automount *a) {
 
         xsprintf(options, "fd=%i,pgrp="PID_FMT",minproto=5,maxproto=5,direct", p[1], getpgrp());
         xsprintf(name, "systemd-"PID_FMT, getpid_cached());
-        if (mount(name, a->where, "autofs", 0, options) < 0) {
-                r = -errno;
+        r = mount_nofollow(name, a->where, "autofs", 0, options);
+        if (r < 0)
                 goto fail;
-        }
 
         mounted = true;
 
index 7d00da214aa1a563ac0b8282a2775897b0a87582..49660c738961aafdd1a9d7319b1729590226cbe2 100644 (file)
@@ -61,11 +61,11 @@ int home_activate_directory(
         /* Create a mount point (even if the directory is already placed correctly), as a way to indicate
          * this mount point is now "activated". Moreover, we want to set per-user
          * MS_NOSUID/MS_NOEXEC/MS_NODEV. */
-        r = mount_verbose(LOG_ERR, ip, hd, NULL, MS_BIND, NULL);
+        r = mount_nofollow_verbose(LOG_ERR, ip, hd, NULL, MS_BIND, NULL);
         if (r < 0)
                 return r;
 
-        r = mount_verbose(LOG_ERR, NULL, hd, NULL, MS_BIND|MS_REMOUNT|user_record_mount_flags(h), NULL);
+        r = mount_nofollow_verbose(LOG_ERR, NULL, hd, NULL, MS_BIND|MS_REMOUNT|user_record_mount_flags(h), NULL);
         if (r < 0) {
                 (void) umount_verbose(hd);
                 return r;
index b3082f144a60dd936a6dec15e922f59cdba13b0a..f13f41e61279ee4a330f8b0424a2565cd16c2650 100644 (file)
@@ -5,6 +5,7 @@
 #include <poll.h>
 #include <sys/file.h>
 #include <sys/ioctl.h>
+#include <sys/mount.h>
 #include <sys/xattr.h>
 
 #include "blkid-util.h"
index 51c0a3864945190b0a8a1741b43a735f295fc880..7c94de49cc55022b861bb6bf58a24419ece2af55 100644 (file)
@@ -38,7 +38,7 @@ int home_mount_node(const char *node, const char *fstype, bool discard, unsigned
         } else
                 options = discard_option;
 
-        r = mount_verbose(LOG_ERR, node, "/run/systemd/user-home-mount", fstype, flags|MS_RELATIME, strempty(options));
+        r = mount_nofollow_verbose(LOG_ERR, node, "/run/systemd/user-home-mount", fstype, flags|MS_RELATIME, strempty(options));
         if (r < 0)
                 return r;
 
@@ -52,7 +52,7 @@ int home_unshare_and_mount(const char *node, const char *fstype, bool discard, u
         if (unshare(CLONE_NEWNS) < 0)
                 return log_error_errno(errno, "Couldn't unshare file system namespace: %m");
 
-        r = mount_verbose(LOG_ERR, "/run", "/run", NULL, MS_SLAVE|MS_REC, NULL); /* Mark /run as MS_SLAVE in our new namespace */
+        r = mount_nofollow_verbose(LOG_ERR, "/run", "/run", NULL, MS_SLAVE|MS_REC, NULL); /* Mark /run as MS_SLAVE in our new namespace */
         if (r < 0)
                 return r;
 
@@ -83,7 +83,7 @@ int home_move_mount(const char *user_name_and_realm, const char *target) {
 
         (void) mkdir_p(target, 0700);
 
-        r = mount_verbose(LOG_ERR, d, target, NULL, MS_BIND, NULL);
+        r = mount_nofollow_verbose(LOG_ERR, d, target, NULL, MS_BIND, NULL);
         if (r < 0)
                 return r;
 
index a16ee5c60a23491ace496cd79b53310c7fbd118f..508b8b6460952990dab1f017988aad670faa7074 100644 (file)
@@ -105,11 +105,11 @@ int sync_cgroup(pid_t pid, CGroupUnified unified_requested, uid_t uid_shift) {
                 return log_error_errno(errno, "Failed to generate temporary mount point for unified hierarchy: %m");
 
         if (unified_controller > 0)
-                r = mount_verbose(LOG_ERR, "cgroup", tree, "cgroup",
-                                  MS_NOSUID|MS_NOEXEC|MS_NODEV, "none,name=systemd,xattr");
+                r = mount_nofollow_verbose(LOG_ERR, "cgroup", tree, "cgroup",
+                                           MS_NOSUID|MS_NOEXEC|MS_NODEV, "none,name=systemd,xattr");
         else
-                r = mount_verbose(LOG_ERR, "cgroup", tree, "cgroup2",
-                                  MS_NOSUID|MS_NOEXEC|MS_NODEV, NULL);
+                r = mount_nofollow_verbose(LOG_ERR, "cgroup", tree, "cgroup2",
+                                           MS_NOSUID|MS_NOEXEC|MS_NODEV, NULL);
         if (r < 0)
                 goto finish;
 
@@ -275,14 +275,14 @@ static int mount_legacy_cgroup_hierarchy(
                 opts = controller;
         }
 
-        r = mount_verbose(LOG_ERR, "cgroup", to, fstype, MS_NOSUID|MS_NOEXEC|MS_NODEV, opts);
+        r = mount_nofollow_verbose(LOG_ERR, "cgroup", to, fstype, MS_NOSUID|MS_NOEXEC|MS_NODEV, opts);
         if (r < 0)
                 return r;
 
         /* ... hence let's only make the bind mount read-only, not the superblock. */
         if (read_only) {
-                r = mount_verbose(LOG_ERR, NULL, to, NULL,
-                                  MS_BIND|MS_REMOUNT|MS_NOSUID|MS_NOEXEC|MS_NODEV|MS_RDONLY, NULL);
+                r = mount_nofollow_verbose(LOG_ERR, NULL, to, NULL,
+                                           MS_BIND|MS_REMOUNT|MS_NOSUID|MS_NOEXEC|MS_NODEV|MS_RDONLY, NULL);
                 if (r < 0)
                         return r;
         }
@@ -323,8 +323,8 @@ static int mount_legacy_cgns_supported(
                 if (r < 0)
                         return log_oom();
 
-                r = mount_verbose(LOG_ERR, "tmpfs", cgroup_root, "tmpfs",
-                                  MS_NOSUID|MS_NOEXEC|MS_NODEV|MS_STRICTATIME, options);
+                r = mount_nofollow_verbose(LOG_ERR, "tmpfs", cgroup_root, "tmpfs",
+                                           MS_NOSUID|MS_NOEXEC|MS_NODEV|MS_STRICTATIME, options);
                 if (r < 0)
                         return r;
         }
@@ -391,8 +391,8 @@ skip_controllers:
                 return r;
 
         if (!userns)
-                return mount_verbose(LOG_ERR, NULL, cgroup_root, NULL,
-                                     MS_REMOUNT|MS_NOSUID|MS_NOEXEC|MS_NODEV|MS_STRICTATIME|MS_RDONLY, "mode=755");
+                return mount_nofollow_verbose(LOG_ERR, NULL, cgroup_root, NULL,
+                                              MS_REMOUNT|MS_NOSUID|MS_NOEXEC|MS_NODEV|MS_STRICTATIME|MS_RDONLY, "mode=755");
 
         return 0;
 }
@@ -425,8 +425,8 @@ static int mount_legacy_cgns_unsupported(
                 if (r < 0)
                         return log_oom();
 
-                r = mount_verbose(LOG_ERR, "tmpfs", cgroup_root, "tmpfs",
-                                  MS_NOSUID|MS_NOEXEC|MS_NODEV|MS_STRICTATIME, options);
+                r = mount_nofollow_verbose(LOG_ERR, "tmpfs", cgroup_root, "tmpfs",
+                                           MS_NOSUID|MS_NOEXEC|MS_NODEV|MS_STRICTATIME, options);
                 if (r < 0)
                         return r;
         }
@@ -499,8 +499,8 @@ skip_controllers:
         if (r < 0)
                 return r;
 
-        return mount_verbose(LOG_ERR, NULL, cgroup_root, NULL,
-                             MS_REMOUNT|MS_NOSUID|MS_NOEXEC|MS_NODEV|MS_STRICTATIME|MS_RDONLY, "mode=755");
+        return mount_nofollow_verbose(LOG_ERR, NULL, cgroup_root, NULL,
+                                      MS_REMOUNT|MS_NOSUID|MS_NOEXEC|MS_NODEV|MS_STRICTATIME|MS_RDONLY, "mode=755");
 }
 
 static int mount_unified_cgroups(const char *dest) {
@@ -527,7 +527,7 @@ static int mount_unified_cgroups(const char *dest) {
                                        "%s is already mounted but not a unified cgroup hierarchy. Refusing.", p);
         }
 
-        return mount_verbose(LOG_ERR, "cgroup", p, "cgroup2", MS_NOSUID|MS_NOEXEC|MS_NODEV, NULL);
+        return mount_nofollow_verbose(LOG_ERR, "cgroup", p, "cgroup2", MS_NOSUID|MS_NOEXEC|MS_NODEV, NULL);
 }
 
 int mount_cgroups(
@@ -554,13 +554,13 @@ static int mount_systemd_cgroup_writable_one(const char *root, const char *own)
         assert(own);
 
         /* Make our own cgroup a (writable) bind mount */
-        r = mount_verbose(LOG_ERR, own, own, NULL, MS_BIND, NULL);
+        r = mount_nofollow_verbose(LOG_ERR, own, own, NULL, MS_BIND, NULL);
         if (r < 0)
                 return r;
 
         /* And then remount the systemd cgroup root read-only */
-        return mount_verbose(LOG_ERR, NULL, root, NULL,
-                             MS_BIND|MS_REMOUNT|MS_NOSUID|MS_NOEXEC|MS_NODEV|MS_RDONLY, NULL);
+        return mount_nofollow_verbose(LOG_ERR, NULL, root, NULL,
+                                      MS_BIND|MS_REMOUNT|MS_NOSUID|MS_NOEXEC|MS_NODEV|MS_RDONLY, NULL);
 }
 
 int mount_systemd_cgroup_writable(
index c49ed7697957263b19457072db6e0ce081d3f281..8c5bcd890d0941f4660ebf4c633245346e6047a4 100644 (file)
@@ -40,7 +40,9 @@ CustomMount* custom_mount_add(CustomMount **l, size_t *n, CustomMountType t) {
         ret = *l + *n;
         (*n)++;
 
-        *ret = (CustomMount) { .type = t };
+        *ret = (CustomMount) {
+                .type = t
+        };
 
         return ret;
 }
@@ -442,8 +444,8 @@ int mount_sysfs(const char *dest, MountSettingsMask mount_settings) {
         if (FLAGS_SET(mount_settings, MOUNT_APPLY_APIVFS_RO))
                 extra_flags |= MS_RDONLY;
 
-        r = mount_verbose(LOG_ERR, "sysfs", full, "sysfs",
-                          MS_NOSUID|MS_NOEXEC|MS_NODEV|extra_flags, NULL);
+        r = mount_nofollow_verbose(LOG_ERR, "sysfs", full, "sysfs",
+                                   MS_NOSUID|MS_NOEXEC|MS_NODEV|extra_flags, NULL);
         if (r < 0)
                 return r;
 
@@ -460,12 +462,12 @@ int mount_sysfs(const char *dest, MountSettingsMask mount_settings) {
 
                 (void) mkdir(to, 0755);
 
-                r = mount_verbose(LOG_ERR, from, to, NULL, MS_BIND, NULL);
+                r = mount_nofollow_verbose(LOG_ERR, from, to, NULL, MS_BIND, NULL);
                 if (r < 0)
                         return r;
 
-                r = mount_verbose(LOG_ERR, NULL, to, NULL,
-                                  MS_BIND|MS_NOSUID|MS_NOEXEC|MS_NODEV|MS_REMOUNT|extra_flags, NULL);
+                r = mount_nofollow_verbose(LOG_ERR, NULL, to, NULL,
+                                           MS_BIND|MS_NOSUID|MS_NOEXEC|MS_NODEV|MS_REMOUNT|extra_flags, NULL);
                 if (r < 0)
                         return r;
         }
@@ -483,8 +485,8 @@ int mount_sysfs(const char *dest, MountSettingsMask mount_settings) {
         x = prefix_roota(top, "/fs/cgroup");
         (void) mkdir_p(x, 0755);
 
-        return mount_verbose(LOG_ERR, NULL, top, NULL,
-                             MS_BIND|MS_NOSUID|MS_NOEXEC|MS_NODEV|MS_REMOUNT|extra_flags, NULL);
+        return mount_nofollow_verbose(LOG_ERR, NULL, top, NULL,
+                                      MS_BIND|MS_NOSUID|MS_NOEXEC|MS_NODEV|MS_REMOUNT|extra_flags, NULL);
 }
 
 int mount_all(const char *dest,
@@ -516,7 +518,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_MKDIR },
+                  MOUNT_FATAL|MOUNT_IN_USERNS|MOUNT_MKDIR|MOUNT_FOLLOW_SYMLINKS }, /* we follow symlinks here since not following them requires /proc/ already being mounted, which we don't have here. */
 
                 { "/proc/sys",       "/proc/sys",       NULL,    NULL,        MS_BIND,
                   MOUNT_FATAL|MOUNT_IN_USERNS|MOUNT_APPLY_APIVFS_RO },                          /* Bind mount first ... */
@@ -670,12 +672,14 @@ int mount_all(const char *dest,
                                 return log_error_errno(r, "Failed to resolve %s/%s: %m", dest, mount_table[k].what);
                 }
 
-                r = mount_verbose(fatal ? LOG_ERR : LOG_DEBUG,
-                                  prefixed ?: mount_table[k].what,
-                                  where,
-                                  mount_table[k].type,
-                                  mount_table[k].flags,
-                                  o);
+                r = mount_verbose_full(
+                                fatal ? LOG_ERR : LOG_DEBUG,
+                                prefixed ?: mount_table[k].what,
+                                where,
+                                mount_table[k].type,
+                                mount_table[k].flags,
+                                o,
+                                FLAGS_SET(mount_table[k].mount_settings, MOUNT_FOLLOW_SYMLINKS));
                 if (r < 0 && fatal)
                         return r;
         }
@@ -771,7 +775,7 @@ static int mount_bind(const char *dest, CustomMount *m) {
                         return log_error_errno(r, "Failed to create mount point %s: %m", where);
         }
 
-        r = mount_verbose(LOG_ERR, m->source, where, NULL, mount_flags, mount_opts);
+        r = mount_nofollow_verbose(LOG_ERR, m->source, where, NULL, mount_flags, mount_opts);
         if (r < 0)
                 return r;
 
@@ -807,7 +811,7 @@ static int mount_tmpfs(const char *dest, CustomMount *m, uid_t uid_shift, const
                 return log_oom();
         options = r > 0 ? buf : m->options;
 
-        return mount_verbose(LOG_ERR, "tmpfs", where, "tmpfs", MS_NODEV|MS_STRICTATIME, options);
+        return mount_nofollow_verbose(LOG_ERR, "tmpfs", where, "tmpfs", MS_NODEV|MS_STRICTATIME, options);
 }
 
 static char *joined_and_escaped_lower_dirs(char **lower) {
@@ -864,7 +868,7 @@ static int mount_overlay(const char *dest, CustomMount *m) {
                 options = strjoina("lowerdir=", lower, ",upperdir=", escaped_source, ",workdir=", escaped_work_dir);
         }
 
-        return mount_verbose(LOG_ERR, "overlay", where, "overlay", m->read_only ? MS_RDONLY : 0, options);
+        return mount_nofollow_verbose(LOG_ERR, "overlay", where, "overlay", m->read_only ? MS_RDONLY : 0, options);
 }
 
 static int mount_inaccessible(const char *dest, CustomMount *m) {
@@ -885,11 +889,11 @@ static int mount_inaccessible(const char *dest, CustomMount *m) {
         if (r < 0)
                 return m->graceful ? 0 : r;
 
-        r = mount_verbose(m->graceful ? LOG_DEBUG : LOG_ERR, source, where, NULL, MS_BIND, NULL);
+        r = mount_nofollow_verbose(m->graceful ? LOG_DEBUG : LOG_ERR, source, where, NULL, MS_BIND, NULL);
         if (r < 0)
                 return m->graceful ? 0 : r;
 
-        r = mount_verbose(m->graceful ? LOG_DEBUG : LOG_ERR, NULL, where, NULL, MS_BIND|MS_RDONLY|MS_REMOUNT, NULL);
+        r = mount_nofollow_verbose(m->graceful ? LOG_DEBUG : LOG_ERR, NULL, where, NULL, MS_BIND|MS_RDONLY|MS_REMOUNT, NULL);
         if (r < 0) {
                 (void) umount_verbose(where);
                 return m->graceful ? 0 : r;
@@ -914,7 +918,7 @@ static int mount_arbitrary(const char *dest, CustomMount *m) {
                         return log_error_errno(r, "Creating mount point for mount %s failed: %m", where);
         }
 
-        return mount_verbose(LOG_ERR, m->source, where, m->type_argument, 0, m->options);
+        return mount_nofollow_verbose(LOG_ERR, m->source, where, m->type_argument, 0, m->options);
 }
 
 int mount_custom(
@@ -1013,7 +1017,7 @@ static int setup_volatile_state(const char *directory, uid_t uid_shift, const ch
         if (r > 0)
                 options = buf;
 
-        return mount_verbose(LOG_ERR, "tmpfs", p, "tmpfs", MS_STRICTATIME, options);
+        return mount_nofollow_verbose(LOG_ERR, "tmpfs", p, "tmpfs", MS_STRICTATIME, options);
 }
 
 static int setup_volatile_yes(const char *directory, uid_t uid_shift, const char *selinux_apifs_context) {
@@ -1058,7 +1062,7 @@ static int setup_volatile_yes(const char *directory, uid_t uid_shift, const char
         if (r > 0)
                 options = buf;
 
-        r = mount_verbose(LOG_ERR, "tmpfs", template, "tmpfs", MS_STRICTATIME, options);
+        r = mount_nofollow_verbose(LOG_ERR, "tmpfs", template, "tmpfs", MS_STRICTATIME, options);
         if (r < 0)
                 goto fail;
 
@@ -1073,7 +1077,7 @@ static int setup_volatile_yes(const char *directory, uid_t uid_shift, const char
                 goto fail;
         }
 
-        r = mount_verbose(LOG_ERR, f, t, NULL, MS_BIND|MS_REC, NULL);
+        r = mount_nofollow_verbose(LOG_ERR, f, t, NULL, MS_BIND|MS_REC, NULL);
         if (r < 0)
                 goto fail;
 
@@ -1085,7 +1089,7 @@ static int setup_volatile_yes(const char *directory, uid_t uid_shift, const char
                 goto fail;
         }
 
-        r = mount_verbose(LOG_ERR, template, directory, NULL, MS_MOVE, NULL);
+        r = mount_nofollow_verbose(LOG_ERR, template, directory, NULL, MS_MOVE, NULL);
         if (r < 0)
                 goto fail;
 
@@ -1125,7 +1129,7 @@ static int setup_volatile_overlay(const char *directory, uid_t uid_shift, const
         if (r > 0)
                 options = buf;
 
-        r = mount_verbose(LOG_ERR, "tmpfs", template, "tmpfs", MS_STRICTATIME, options);
+        r = mount_nofollow_verbose(LOG_ERR, "tmpfs", template, "tmpfs", MS_STRICTATIME, options);
         if (r < 0)
                 goto finish;
 
@@ -1155,7 +1159,7 @@ static int setup_volatile_overlay(const char *directory, uid_t uid_shift, const
         }
 
         options = strjoina("lowerdir=", escaped_directory, ",upperdir=", escaped_upper, ",workdir=", escaped_work);
-        r = mount_verbose(LOG_ERR, "overlay", directory, "overlay", 0, options);
+        r = mount_nofollow_verbose(LOG_ERR, "overlay", directory, "overlay", 0, options);
 
 finish:
         if (tmpfs_mounted)
@@ -1265,7 +1269,7 @@ int setup_pivot_root(const char *directory, const char *pivot_root_new, const ch
                 return log_oom();
 
         /* Remount directory_pivot_root_new to make it movable. */
-        r = mount_verbose(LOG_ERR, directory_pivot_root_new, directory_pivot_root_new, NULL, MS_BIND, NULL);
+        r = mount_nofollow_verbose(LOG_ERR, directory_pivot_root_new, directory_pivot_root_new, NULL, MS_BIND, NULL);
         if (r < 0)
                 goto done;
 
@@ -1282,19 +1286,19 @@ int setup_pivot_root(const char *directory, const char *pivot_root_new, const ch
                         goto done;
                 }
 
-                r = mount_verbose(LOG_ERR, directory_pivot_root_new, pivot_tmp, NULL, MS_MOVE, NULL);
+                r = mount_nofollow_verbose(LOG_ERR, directory_pivot_root_new, pivot_tmp, NULL, MS_MOVE, NULL);
                 if (r < 0)
                         goto done;
 
-                r = mount_verbose(LOG_ERR, directory, pivot_tmp_pivot_root_old, NULL, MS_MOVE, NULL);
+                r = mount_nofollow_verbose(LOG_ERR, directory, pivot_tmp_pivot_root_old, NULL, MS_MOVE, NULL);
                 if (r < 0)
                         goto done;
 
-                r = mount_verbose(LOG_ERR, pivot_tmp, directory, NULL, MS_MOVE, NULL);
+                r = mount_nofollow_verbose(LOG_ERR, pivot_tmp, directory, NULL, MS_MOVE, NULL);
                 if (r < 0)
                         goto done;
         } else {
-                r = mount_verbose(LOG_ERR, directory_pivot_root_new, directory, NULL, MS_MOVE, NULL);
+                r = mount_nofollow_verbose(LOG_ERR, directory_pivot_root_new, directory, NULL, MS_MOVE, NULL);
                 if (r < 0)
                         goto done;
         }
index 3898c74f18eaaf0897d769288df3b064ad882c33..8f9d094fae027f228569c3a98719ce3d7bf75763 100644 (file)
@@ -19,6 +19,7 @@ typedef enum MountSettingsMask {
         MOUNT_MKDIR              = 1 << 8, /* if set, make directory to mount over first */
         MOUNT_TOUCH              = 1 << 9, /* if set, touch file to mount over first */
         MOUNT_PREFIX_ROOT        = 1 << 10,/* if set, prefix the source path with the container's root directory */
+        MOUNT_FOLLOW_SYMLINKS    = 1 << 11,/* if set, we'll follow symlinks for the mount target */
 } MountSettingsMask;
 
 typedef enum CustomMountType {
index 9ab131ef9b8e3a7184d6691f2c3ae614e3296296..ea5be3f72dadc2505e35cf9f5e004f0425ab45fb 100644 (file)
@@ -1918,9 +1918,9 @@ static int setup_timezone(const char *dest) {
                 if (found == 0) /* missing? */
                         (void) touch(resolved);
 
-                r = mount_verbose(LOG_WARNING, "/etc/localtime", resolved, NULL, MS_BIND, NULL);
+                r = mount_nofollow_verbose(LOG_WARNING, "/etc/localtime", resolved, NULL, MS_BIND, NULL);
                 if (r >= 0)
-                        return mount_verbose(LOG_ERR, NULL, resolved, NULL, MS_BIND|MS_REMOUNT|MS_RDONLY|MS_NOSUID|MS_NODEV, NULL);
+                        return mount_nofollow_verbose(LOG_ERR, NULL, resolved, NULL, MS_BIND|MS_REMOUNT|MS_RDONLY|MS_NOSUID|MS_NODEV, NULL);
 
                 _fallthrough_;
         }
@@ -2053,9 +2053,9 @@ static int setup_resolv_conf(const char *dest) {
                 if (found == 0) /* missing? */
                         (void) touch(resolved);
 
-                r = mount_verbose(LOG_WARNING, what, resolved, NULL, MS_BIND, NULL);
+                r = mount_nofollow_verbose(LOG_WARNING, what, resolved, NULL, MS_BIND, NULL);
                 if (r >= 0)
-                        return mount_verbose(LOG_ERR, NULL, resolved, NULL, MS_BIND|MS_REMOUNT|MS_RDONLY|MS_NOSUID|MS_NODEV, NULL);
+                        return mount_nofollow_verbose(LOG_ERR, NULL, resolved, NULL, MS_BIND|MS_REMOUNT|MS_RDONLY|MS_NOSUID|MS_NODEV, NULL);
 
                 /* If that didn't work, let's copy the file */
         }
@@ -2107,11 +2107,11 @@ static int setup_boot_id(void) {
         from = TAKE_PTR(path);
         to = "/proc/sys/kernel/random/boot_id";
 
-        r = mount_verbose(LOG_ERR, from, to, NULL, MS_BIND, NULL);
+        r = mount_nofollow_verbose(LOG_ERR, from, to, NULL, MS_BIND, NULL);
         if (r < 0)
                 return r;
 
-        return mount_verbose(LOG_ERR, NULL, to, NULL, MS_BIND|MS_REMOUNT|MS_RDONLY|MS_NOSUID|MS_NOEXEC|MS_NODEV, NULL);
+        return mount_nofollow_verbose(LOG_ERR, NULL, to, NULL, MS_BIND|MS_REMOUNT|MS_RDONLY|MS_NOSUID|MS_NOEXEC|MS_NODEV, NULL);
 }
 
 static int copy_devnodes(const char *dest) {
@@ -2170,7 +2170,7 @@ static int copy_devnodes(const char *dest) {
                                 r = touch(to);
                                 if (r < 0)
                                         return log_error_errno(r, "touch (%s) failed: %m", to);
-                                r = mount_verbose(LOG_DEBUG, from, to, NULL, MS_BIND, NULL);
+                                r = mount_nofollow_verbose(LOG_DEBUG, from, to, NULL, MS_BIND, NULL);
                                 if (r < 0)
                                         return log_error_errno(r, "Both mknod and bind mount (%s) failed: %m", to);
                         }
@@ -2258,7 +2258,7 @@ static int setup_pts(const char *dest) {
         if (r < 0)
                 return log_error_errno(r, "Failed to create /dev/pts: %m");
 
-        r = mount_verbose(LOG_ERR, "devpts", p, "devpts", MS_NOSUID|MS_NOEXEC, options);
+        r = mount_nofollow_verbose(LOG_ERR, "devpts", p, "devpts", MS_NOSUID|MS_NOEXEC, options);
         if (r < 0)
                 return r;
         r = userns_lchown(p, 0, 0);
@@ -2360,7 +2360,7 @@ static int setup_credentials(const char *root) {
                 return log_error_errno(r, "Failed to create /run/host/credentials: %m");
 
         q = prefix_roota(root, "/run/host/credentials");
-        r = mount_verbose(LOG_ERR, NULL, q, "ramfs", MS_NOSUID|MS_NOEXEC|MS_NODEV, "mode=0700");
+        r = mount_nofollow_verbose(LOG_ERR, NULL, q, "ramfs", MS_NOSUID|MS_NOEXEC|MS_NODEV, "mode=0700");
         if (r < 0)
                 return r;
 
@@ -2397,11 +2397,11 @@ static int setup_credentials(const char *root) {
                 return r;
 
         /* Make both mount and superblock read-only now */
-        r = mount_verbose(LOG_ERR, NULL, q, NULL, MS_REMOUNT|MS_BIND|MS_RDONLY|MS_NOSUID|MS_NOEXEC|MS_NODEV, NULL);
+        r = mount_nofollow_verbose(LOG_ERR, NULL, q, NULL, MS_REMOUNT|MS_BIND|MS_RDONLY|MS_NOSUID|MS_NOEXEC|MS_NODEV, NULL);
         if (r < 0)
                 return r;
 
-        return mount_verbose(LOG_ERR, NULL, q, NULL, MS_REMOUNT|MS_RDONLY|MS_NOSUID|MS_NOEXEC|MS_NODEV, "mode=0500");
+        return mount_nofollow_verbose(LOG_ERR, NULL, q, NULL, MS_REMOUNT|MS_RDONLY|MS_NOSUID|MS_NOEXEC|MS_NODEV, "mode=0500");
 }
 
 static int setup_kmsg(int kmsg_socket) {
@@ -2429,7 +2429,7 @@ static int setup_kmsg(int kmsg_socket) {
 
         from = TAKE_PTR(fifo);
 
-        r = mount_verbose(LOG_ERR, from, "/proc/kmsg", NULL, MS_BIND, NULL);
+        r = mount_nofollow_verbose(LOG_ERR, from, "/proc/kmsg", NULL, MS_BIND, NULL);
         if (r < 0)
                 return r;
 
@@ -2595,7 +2595,7 @@ static int setup_journal(const char *directory) {
         if (r < 0)
                 return log_error_errno(r, "Failed to create %s: %m", q);
 
-        r = mount_verbose(LOG_DEBUG, p, q, NULL, MS_BIND, NULL);
+        r = mount_nofollow_verbose(LOG_DEBUG, p, q, NULL, MS_BIND, NULL);
         if (r < 0)
                 return log_error_errno(errno, "Failed to bind mount journal from host into guest: %m");
 
@@ -2700,16 +2700,16 @@ static int setup_propagate(const char *root) {
                 return log_error_errno(r, "Failed to create /run/host/incoming: %m");
 
         q = prefix_roota(root, "/run/host/incoming");
-        r = mount_verbose(LOG_ERR, p, q, NULL, MS_BIND, NULL);
+        r = mount_nofollow_verbose(LOG_ERR, p, q, NULL, MS_BIND, NULL);
         if (r < 0)
                 return r;
 
-        r = mount_verbose(LOG_ERR, NULL, q, NULL, MS_BIND|MS_REMOUNT|MS_RDONLY, NULL);
+        r = mount_nofollow_verbose(LOG_ERR, NULL, q, NULL, MS_BIND|MS_REMOUNT|MS_RDONLY, NULL);
         if (r < 0)
                 return r;
 
         /* machined will MS_MOVE into that directory, and that's only supported for non-shared mounts. */
-        return mount_verbose(LOG_ERR, NULL, q, NULL, MS_SLAVE, NULL);
+        return mount_nofollow_verbose(LOG_ERR, NULL, q, NULL, MS_SLAVE, NULL);
 }
 
 static int setup_machine_id(const char *directory) {
@@ -3157,7 +3157,7 @@ static int inner_child(
                 /* Creating a new user namespace means all MS_SHARED mounts become MS_SLAVE. Let's put them
                  * back to MS_SHARED here, since that's what we want as defaults. (This will not reconnect
                  * propagation, but simply create new peer groups for all our mounts). */
-                r = mount_verbose(LOG_ERR, NULL, "/", NULL, MS_SHARED|MS_REC, NULL);
+                r = mount_follow_verbose(LOG_ERR, NULL, "/", NULL, MS_SHARED|MS_REC, NULL);
                 if (r < 0)
                         return r;
         }
@@ -3542,7 +3542,7 @@ static int outer_child(
 
         /* Mark everything as slave, so that we still receive mounts from the real root, but don't propagate
          * mounts to the real root. */
-        r = mount_verbose(LOG_ERR, NULL, "/", NULL, MS_SLAVE|MS_REC, NULL);
+        r = mount_follow_verbose(LOG_ERR, NULL, "/", NULL, MS_SLAVE|MS_REC, NULL);
         if (r < 0)
                 return r;
 
@@ -3600,7 +3600,7 @@ static int outer_child(
                  * already, and thus don't need to be afraid of colliding with anyone else's mounts).*/
                 (void) mkdir_p("/run/systemd/nspawn-root", 0755);
 
-                r = mount_verbose(LOG_ERR, "/", "/run/systemd/nspawn-root", NULL, MS_BIND|MS_REC, NULL);
+                r = mount_nofollow_verbose(LOG_ERR, "/", "/run/systemd/nspawn-root", NULL, MS_BIND|MS_REC, NULL);
                 if (r < 0)
                         return r;
 
@@ -3634,7 +3634,7 @@ static int outer_child(
 
         /* Make sure we always have a mount that we can move to root later on. */
         if (!path_is_mount_point(directory, NULL, 0)) {
-                r = mount_verbose(LOG_ERR, directory, directory, NULL, MS_BIND|MS_REC, NULL);
+                r = mount_nofollow_verbose(LOG_ERR, directory, directory, NULL, MS_BIND|MS_REC, NULL);
                 if (r < 0)
                         return r;
         }
@@ -3677,7 +3677,7 @@ static int outer_child(
          * enable moving the root directory mount to root later on.
          * https://github.com/systemd/systemd/issues/3847#issuecomment-562735251
          */
-        r = mount_verbose(LOG_ERR, NULL, directory, NULL, MS_SHARED|MS_REC, NULL);
+        r = mount_nofollow_verbose(LOG_ERR, NULL, directory, NULL, MS_SHARED|MS_REC, NULL);
         if (r < 0)
                 return r;
 
index b30a6894fb62cfd66dc51d8e4346879d92f1dfbc..3e1dcf53ebc7ccb45c4ab1eef3e7e72c64856648 100644 (file)
@@ -2691,7 +2691,7 @@ static int partition_copy_files(Partition *p, const char *node) {
                         _exit(EXIT_FAILURE);
                 }
 
-                if (mount_verbose(LOG_ERR, node, fs, p->format, MS_NOATIME|MS_NODEV|MS_NOEXEC|MS_NOSUID, NULL) < 0)
+                if (mount_nofollow_verbose(LOG_ERR, node, fs, p->format, MS_NOATIME|MS_NODEV|MS_NOEXEC|MS_NOSUID, NULL) < 0)
                         _exit(EXIT_FAILURE);
 
                 if (do_copy_files(p, fs) < 0)
index 3a2200f91e735db5c3978256a9b03d8e8f75482c..eaf44f156c67e5acb0256f30505b7d8a81870bbc 100644 (file)
@@ -1177,7 +1177,7 @@ static int mount_partition(
                         return r;
         }
 
-        r = mount_verbose(LOG_DEBUG, node, p, fstype, MS_NODEV|(rw ? 0 : MS_RDONLY), options);
+        r = mount_nofollow_verbose(LOG_DEBUG, node, p, fstype, MS_NODEV|(rw ? 0 : MS_RDONLY), options);
         if (r < 0)
                 return r;
 
index 0b76b77430f085d5532c66314b218feadc283f46..9ff96bd3be838b3bc8ce35ac4b620ad9ddcf7b77 100644 (file)
@@ -312,14 +312,16 @@ int bind_remount_recursive_with_mountinfo(
                 if (!set_contains(done, simplified) &&
                     !set_contains(todo, simplified)) {
                         /* The prefix directory itself is not yet a mount, make it one. */
-                        if (mount(simplified, simplified, NULL, MS_BIND|MS_REC, NULL) < 0)
-                                return -errno;
+                        r = mount_nofollow(simplified, simplified, NULL, MS_BIND|MS_REC, NULL);
+                        if (r < 0)
+                                return r;
 
                         orig_flags = 0;
                         (void) get_mount_flags(table, simplified, &orig_flags);
 
-                        if (mount(NULL, simplified, NULL, (orig_flags & ~flags_mask)|MS_BIND|MS_REMOUNT|new_flags, NULL) < 0)
-                                return -errno;
+                        r = mount_nofollow(NULL, simplified, NULL, (orig_flags & ~flags_mask)|MS_BIND|MS_REMOUNT|new_flags, NULL);
+                        if (r < 0)
+                                return r;
 
                         log_debug("Made top-level directory %s a mount point.", prefix);
 
@@ -360,8 +362,9 @@ int bind_remount_recursive_with_mountinfo(
                         orig_flags = 0;
                         (void) get_mount_flags(table, x, &orig_flags);
 
-                        if (mount(NULL, x, NULL, (orig_flags & ~flags_mask)|MS_BIND|MS_REMOUNT|new_flags, NULL) < 0)
-                                return -errno;
+                        r = mount_nofollow(NULL, x, NULL, (orig_flags & ~flags_mask)|MS_BIND|MS_REMOUNT|new_flags, NULL);
+                        if (r < 0)
+                                return r;
 
                         log_debug("Remounted %s read-only.", x);
                 }
@@ -410,8 +413,9 @@ int bind_remount_one_with_mountinfo(
         /* Try to reuse the original flag set */
         (void) get_mount_flags(table, path, &orig_flags);
 
-        if (mount(NULL, path, NULL, (orig_flags & ~flags_mask)|MS_BIND|MS_REMOUNT|new_flags, NULL) < 0)
-                return -errno;
+        r = mount_nofollow(NULL, path, NULL, (orig_flags & ~flags_mask)|MS_BIND|MS_REMOUNT|new_flags, NULL);
+        if (r < 0)
+                return r;
 
         return 0;
 }
@@ -606,13 +610,14 @@ static char* mount_flags_to_string(long unsigned flags) {
         return x;
 }
 
-int mount_verbose(
+int mount_verbose_full(
                 int error_log_level,
                 const char *what,
                 const char *where,
                 const char *type,
                 unsigned long flags,
-                const char *options) {
+                const char *options,
+                bool follow_symlink) {
 
         _cleanup_free_ char *fl = NULL, *o = NULL;
         unsigned long f;
@@ -641,8 +646,13 @@ int mount_verbose(
         else
                 log_debug("Mounting %s on %s (%s \"%s\")...",
                           strna(type), where, strnull(fl), strempty(o));
-        if (mount(what, where, type, f, o) < 0)
-                return log_full_errno(error_log_level, errno,
+
+        if (follow_symlink)
+                r = mount(what, where, type, f, o) < 0 ? -errno : 0;
+        else
+                r = mount_nofollow(what, where, type, f, o);
+        if (r < 0)
+                return log_full_errno(error_log_level, r,
                                       "Failed to mount %s (type %s) on %s (%s \"%s\"): %m",
                                       strna(what), strna(type), where, strnull(fl), strempty(o));
         return 0;
index 3c74ad44876c681f76dd63457c7ab13ddcb43a55..b377e68851a671afa7d95374a7a12b065ad968f2 100644 (file)
@@ -46,13 +46,35 @@ int mount_move_root(const char *path);
 DEFINE_TRIVIAL_CLEANUP_FUNC(FILE*, endmntent);
 #define _cleanup_endmntent_ _cleanup_(endmntentp)
 
-int mount_verbose(
+int mount_verbose_full(
                 int error_log_level,
                 const char *what,
                 const char *where,
                 const char *type,
                 unsigned long flags,
-                const char *options);
+                const char *options,
+                bool follow_symlink);
+
+static inline int mount_follow_verbose(
+                int error_log_level,
+                const char *what,
+                const char *where,
+                const char *type,
+                unsigned long flags,
+                const char *options) {
+        return mount_verbose_full(error_log_level, what, where, type, flags, options, true);
+}
+
+static inline int mount_nofollow_verbose(
+                int error_log_level,
+                const char *what,
+                const char *where,
+                const char *type,
+                unsigned long flags,
+                const char *options) {
+        return mount_verbose_full(error_log_level, what, where, type, flags, options, false);
+}
+
 int umount_verbose(const char *where);
 
 int mount_option_mangle(
index 006fdb650fe9a42e1e111ff8ab9c8af2226283a4..00cab7bb45c988cae8da088c782ad3b389df80a5 100644 (file)
@@ -45,8 +45,8 @@ static int fake_filesystems(void) {
                 return log_error_errno(r, "Failed to detach mount namespace: %m");
 
         for (size_t i = 0; i < ELEMENTSOF(fakefss); i++) {
-                r = mount_verbose(fakefss[i].ignore_mount_error ? LOG_NOTICE : LOG_ERR,
-                                  fakefss[i].src, fakefss[i].target, NULL, MS_BIND, NULL);
+                r = mount_nofollow_verbose(fakefss[i].ignore_mount_error ? LOG_NOTICE : LOG_ERR,
+                                           fakefss[i].src, fakefss[i].target, NULL, MS_BIND, NULL);
                 if (r < 0 && !fakefss[i].ignore_mount_error)
                         return r;
         }
index 6a084642454a219686e7ecb517d493ee53e35e40..35c045630f042f8d6e4f98442442fad0bdce2abe 100644 (file)
@@ -29,7 +29,7 @@ static int make_volatile(const char *path) {
         if (r < 0)
                 return log_error_errno(r, "Couldn't generate volatile sysroot directory: %m");
 
-        r = mount_verbose(LOG_ERR, "tmpfs", "/run/systemd/volatile-sysroot", "tmpfs", MS_STRICTATIME, "mode=755" TMPFS_LIMITS_ROOTFS);
+        r = mount_nofollow_verbose(LOG_ERR, "tmpfs", "/run/systemd/volatile-sysroot", "tmpfs", MS_STRICTATIME, "mode=755" TMPFS_LIMITS_ROOTFS);
         if (r < 0)
                 goto finish_rmdir;
 
@@ -38,7 +38,7 @@ static int make_volatile(const char *path) {
                 goto finish_umount;
         }
 
-        r = mount_verbose(LOG_ERR, old_usr, "/run/systemd/volatile-sysroot/usr", NULL, MS_BIND|MS_REC, NULL);
+        r = mount_nofollow_verbose(LOG_ERR, old_usr, "/run/systemd/volatile-sysroot/usr", NULL, MS_BIND|MS_REC, NULL);
         if (r < 0)
                 goto finish_umount;
 
@@ -57,7 +57,7 @@ static int make_volatile(const char *path) {
         if (mount(NULL, "/", NULL, MS_SLAVE|MS_REC, NULL) < 0)
                 log_warning_errno(errno, "Failed to remount %s MS_SLAVE|MS_REC, ignoring: %m", path);
 
-        r = mount_verbose(LOG_ERR, "/run/systemd/volatile-sysroot", path, NULL, MS_MOVE, NULL);
+        r = mount_nofollow_verbose(LOG_ERR, "/run/systemd/volatile-sysroot", path, NULL, MS_MOVE, NULL);
 
 finish_umount:
         (void) umount_recursive("/run/systemd/volatile-sysroot", 0);
@@ -80,7 +80,7 @@ static int make_overlay(const char *path) {
         if (r < 0)
                 return log_error_errno(r, "Couldn't create overlay sysroot directory: %m");
 
-        r = mount_verbose(LOG_ERR, "tmpfs", "/run/systemd/overlay-sysroot", "tmpfs", MS_STRICTATIME, "mode=755" TMPFS_LIMITS_ROOTFS);
+        r = mount_nofollow_verbose(LOG_ERR, "tmpfs", "/run/systemd/overlay-sysroot", "tmpfs", MS_STRICTATIME, "mode=755" TMPFS_LIMITS_ROOTFS);
         if (r < 0)
                 goto finish;
 
@@ -103,7 +103,7 @@ static int make_overlay(const char *path) {
         }
 
         options = strjoina("lowerdir=", escaped_path, ",upperdir=/run/systemd/overlay-sysroot/upper,workdir=/run/systemd/overlay-sysroot/work");
-        r = mount_verbose(LOG_ERR, "overlay", path, "overlay", 0, options);
+        r = mount_nofollow_verbose(LOG_ERR, "overlay", path, "overlay", 0, options);
 
 finish:
         if (tmpfs_mounted)