From 64e82c1976ebab0c7788149da42e5193e9ca2dfb Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Mon, 25 Mar 2019 17:04:38 +0100 Subject: [PATCH] mount-util: beef up bind_remount_recursive() to be able to toggle more than MS_RDONLY 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 | 2 +- src/nspawn/nspawn-mount.c | 6 +++--- src/nspawn/nspawn.c | 2 +- src/shared/mount-util.c | 21 +++++++++++++-------- src/shared/mount-util.h | 4 ++-- src/volatile-root/volatile-root.c | 2 +- 6 files changed, 21 insertions(+), 16 deletions(-) diff --git a/src/core/namespace.c b/src/core/namespace.c index c6179cdb17..455240459a 100644 --- a/src/core/namespace.c +++ b/src/core/namespace.c @@ -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 diff --git a/src/nspawn/nspawn-mount.c b/src/nspawn/nspawn-mount.c index a3447d948a..707d0643b4 100644 --- a/src/nspawn/nspawn-mount.c +++ b/src/nspawn/nspawn-mount.c @@ -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; diff --git a/src/nspawn/nspawn.c b/src/nspawn/nspawn.c index 5ff02130d6..96a93cde25 100644 --- a/src/nspawn/nspawn.c +++ b/src/nspawn/nspawn.c @@ -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"); } diff --git a/src/shared/mount-util.c b/src/shared/mount-util.c index 72cf6c41b6..9dcf49c0a2 100644 --- a/src/shared/mount-util.c +++ b/src/shared/mount-util.c @@ -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) { diff --git a/src/shared/mount-util.h b/src/shared/mount-util.h index 00df1b0e55..8649fca39b 100644 --- a/src/shared/mount-util.h +++ b/src/shared/mount-util.h @@ -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); diff --git a/src/volatile-root/volatile-root.c b/src/volatile-root/volatile-root.c index 701f5a2832..d1193a7a24 100644 --- a/src/volatile-root/volatile-root.c +++ b/src/volatile-root/volatile-root.c @@ -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;