mount-util: beef up bind_remount_recursive() to be able to toggle more than MS_RDONLY
authorLennart Poettering <lennart@poettering.net>
Mon, 25 Mar 2019 16:04:38 +0000 (17:04 +0100)
committerLennart Poettering <lennart@poettering.net>
Mon, 25 Mar 2019 18:33:55 +0000 (19:33 +0100)
The function is otherwise generic enough to toggle other bind mount
flags beyond MS_RDONLY (for example: MS_NOSUID or MS_NODEV), hence let's
beef it up slightly to support that too.

src/core/namespace.c
src/nspawn/nspawn-mount.c
src/nspawn/nspawn.c
src/shared/mount-util.c
src/shared/mount-util.h
src/volatile-root/volatile-root.c

index c6179cd..4552404 100644 (file)
@@ -1062,7 +1062,7 @@ static int make_read_only(const MountEntry *m, char **blacklist, FILE *proc_self
                         r = remount_bind_readonly(mount_entry_path(m), m->flags);
                 else {
                         submounts = true;
-                        r = bind_remount_recursive_with_mountinfo(mount_entry_path(m), true, blacklist, proc_self_mountinfo);
+                        r = bind_remount_recursive_with_mountinfo(mount_entry_path(m), MS_RDONLY, MS_RDONLY, blacklist, proc_self_mountinfo);
                 }
         } else if (m->mode == PRIVATE_DEV)
                 /* Set /dev readonly, but not submounts like /dev/shm. Also, we only set the per-mount
index a3447d9..707d064 100644 (file)
@@ -730,7 +730,7 @@ static int mount_bind(const char *dest, CustomMount *m) {
                 return r;
 
         if (m->read_only) {
-                r = bind_remount_recursive(where, true, NULL);
+                r = bind_remount_recursive(where, MS_RDONLY, MS_RDONLY, NULL);
                 if (r < 0)
                         return log_error_errno(r, "Read-only bind mount failed: %m");
         }
@@ -938,7 +938,7 @@ static int setup_volatile_state(
 
         /* --volatile=state means we simply overmount /var with a tmpfs, and the rest read-only. */
 
-        r = bind_remount_recursive(directory, true, NULL);
+        r = bind_remount_recursive(directory, MS_RDONLY, MS_RDONLY, NULL);
         if (r < 0)
                 return log_error_errno(r, "Failed to remount %s read-only: %m", directory);
 
@@ -1004,7 +1004,7 @@ static int setup_volatile_yes(
 
         bind_mounted = true;
 
-        r = bind_remount_recursive(t, true, NULL);
+        r = bind_remount_recursive(t, MS_RDONLY, MS_RDONLY, NULL);
         if (r < 0) {
                 log_error_errno(r, "Failed to remount %s read-only: %m", t);
                 goto fail;
index 5ff0213..96a93cd 100644 (file)
@@ -3323,7 +3323,7 @@ static int outer_child(
                 return r;
 
         if (arg_read_only && arg_volatile_mode == VOLATILE_NO) {
-                r = bind_remount_recursive(directory, true, NULL);
+                r = bind_remount_recursive(directory, MS_RDONLY, MS_RDONLY, NULL);
                 if (r < 0)
                         return log_error_errno(r, "Failed to make tree read-only: %m");
         }
index 72cf6c4..9dcf49c 100644 (file)
@@ -107,10 +107,15 @@ static int get_mount_flags(const char *path, unsigned long *flags) {
         return 0;
 }
 
-/* Use this function only if do you have direct access to /proc/self/mountinfo
- * and need the caller to open it for you. This is the case when /proc is
- * masked or not mounted. Otherwise, use bind_remount_recursive. */
-int bind_remount_recursive_with_mountinfo(const char *prefix, bool ro, char **blacklist, FILE *proc_self_mountinfo) {
+/* Use this function only if do you have direct access to /proc/self/mountinfo and need the caller to open it
+ * for you. This is the case when /proc is masked or not mounted. Otherwise, use bind_remount_recursive. */
+int bind_remount_recursive_with_mountinfo(
+                const char *prefix,
+                unsigned long new_flags,
+                unsigned long flags_mask,
+                char **blacklist,
+                FILE *proc_self_mountinfo) {
+
         _cleanup_set_free_free_ Set *done = NULL;
         _cleanup_free_ char *cleaned = NULL;
         int r;
@@ -245,7 +250,7 @@ int bind_remount_recursive_with_mountinfo(const char *prefix, bool ro, char **bl
                         (void) get_mount_flags(cleaned, &orig_flags);
                         orig_flags &= ~MS_RDONLY;
 
-                        if (mount(NULL, cleaned, NULL, orig_flags|MS_BIND|MS_REMOUNT|(ro ? MS_RDONLY : 0), NULL) < 0)
+                        if (mount(NULL, cleaned, NULL, (orig_flags & ~flags_mask)|MS_BIND|MS_REMOUNT|new_flags, NULL) < 0)
                                 return -errno;
 
                         log_debug("Made top-level directory %s a mount point.", prefix);
@@ -287,7 +292,7 @@ int bind_remount_recursive_with_mountinfo(const char *prefix, bool ro, char **bl
                         (void) get_mount_flags(x, &orig_flags);
                         orig_flags &= ~MS_RDONLY;
 
-                        if (mount(NULL, x, NULL, orig_flags|MS_BIND|MS_REMOUNT|(ro ? MS_RDONLY : 0), NULL) < 0)
+                        if (mount(NULL, x, NULL, (orig_flags & ~flags_mask)|MS_BIND|MS_REMOUNT|new_flags, NULL) < 0)
                                 return -errno;
 
                         log_debug("Remounted %s read-only.", x);
@@ -295,7 +300,7 @@ int bind_remount_recursive_with_mountinfo(const char *prefix, bool ro, char **bl
         }
 }
 
-int bind_remount_recursive(const char *prefix, bool ro, char **blacklist) {
+int bind_remount_recursive(const char *prefix, unsigned long new_flags, unsigned long flags_mask, char **blacklist) {
         _cleanup_fclose_ FILE *proc_self_mountinfo = NULL;
 
         proc_self_mountinfo = fopen("/proc/self/mountinfo", "re");
@@ -304,7 +309,7 @@ int bind_remount_recursive(const char *prefix, bool ro, char **blacklist) {
 
         (void) __fsetlocking(proc_self_mountinfo, FSETLOCKING_BYCALLER);
 
-        return bind_remount_recursive_with_mountinfo(prefix, ro, blacklist, proc_self_mountinfo);
+        return bind_remount_recursive_with_mountinfo(prefix, new_flags, flags_mask, blacklist, proc_self_mountinfo);
 }
 
 int mount_move_root(const char *path) {
index 00df1b0..8649fca 100644 (file)
@@ -8,8 +8,8 @@
 
 int repeat_unmount(const char *path, int flags);
 int umount_recursive(const char *target, int flags);
-int bind_remount_recursive(const char *prefix, bool ro, char **blacklist);
-int bind_remount_recursive_with_mountinfo(const char *prefix, bool ro, char **blacklist, FILE *proc_self_mountinfo);
+int bind_remount_recursive(const char *prefix, unsigned long new_flags, unsigned long flags_mask, char **blacklist);
+int bind_remount_recursive_with_mountinfo(const char *prefix, unsigned long new_flags, unsigned long flags_mask, char **blacklist, FILE *proc_self_mountinfo);
 
 int mount_move_root(const char *path);
 
index 701f5a2..d1193a7 100644 (file)
@@ -42,7 +42,7 @@ static int make_volatile(const char *path) {
         if (r < 0)
                 goto finish_umount;
 
-        r = bind_remount_recursive("/run/systemd/volatile-sysroot/usr", true, NULL);
+        r = bind_remount_recursive("/run/systemd/volatile-sysroot/usr", MS_RDONLY, MS_RDONLY, NULL);
         if (r < 0) {
                 log_error_errno(r, "Failed to remount /usr read-only: %m");
                 goto finish_umount;