From: Timothée Ravier Date: Fri, 19 May 2017 12:38:40 +0000 (+0200) Subject: core: open /proc/self/mountinfo early to allow mounts over /proc (#5985) X-Git-Tag: chiark/234.4-1+devuan1.1+iwj1~123 X-Git-Url: http://www.chiark.greenend.org.uk/ucgi/~ianmdlvl/git?a=commitdiff_plain;h=5c4d519ec1edd17ef53cd19ad41b5f359aca975c;p=elogind.git core: open /proc/self/mountinfo early to allow mounts over /proc (#5985) Enable masking the /proc folder using the 'InaccessiblePaths' unit option. This also slightly simplify mounts setup as the bind_remount_recursive function will only open /proc/self/mountinfo once. This is based on the suggestion at: https://lists.freedesktop.org/archives/elogind-devel/2017-April/038634.html --- diff --git a/src/basic/mount-util.c b/src/basic/mount-util.c index fef991207..aee878e88 100644 --- a/src/basic/mount-util.c +++ b/src/basic/mount-util.c @@ -317,11 +317,16 @@ static int get_mount_flags(const char *path, unsigned long *flags) { return 0; } -int bind_remount_recursive(const char *prefix, bool ro, char **blacklist) { +/* 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) { _cleanup_set_free_free_ Set *done = NULL; _cleanup_free_ char *cleaned = NULL; int r; + assert(proc_self_mountinfo); + /* Recursively remount a directory (and all its submounts) read-only or read-write. If the directory is already * mounted, we reuse the mount and simply mark it MS_BIND|MS_RDONLY (or remove the MS_RDONLY for read-write * operation). If it isn't we first make it one. Afterwards we apply MS_BIND|MS_RDONLY (or remove MS_RDONLY) to @@ -344,7 +349,6 @@ int bind_remount_recursive(const char *prefix, bool ro, char **blacklist) { return -ENOMEM; for (;;) { - _cleanup_fclose_ FILE *proc_self_mountinfo = NULL; _cleanup_set_free_free_ Set *todo = NULL; bool top_autofs = false; char *x; @@ -354,9 +358,7 @@ int bind_remount_recursive(const char *prefix, bool ro, char **blacklist) { if (!todo) return -ENOMEM; - proc_self_mountinfo = fopen("/proc/self/mountinfo", "re"); - if (!proc_self_mountinfo) - return -errno; + rewind(proc_self_mountinfo); for (;;) { _cleanup_free_ char *path = NULL, *p = NULL, *type = NULL; @@ -495,6 +497,16 @@ int bind_remount_recursive(const char *prefix, bool ro, char **blacklist) { } } +int bind_remount_recursive(const char *prefix, bool ro, char **blacklist) { + _cleanup_fclose_ FILE *proc_self_mountinfo = NULL; + + proc_self_mountinfo = fopen("/proc/self/mountinfo", "re"); + if (!proc_self_mountinfo) + return -errno; + + return bind_remount_recursive_with_mountinfo(prefix, ro, blacklist, proc_self_mountinfo); +} + int mount_move_root(const char *path) { assert(path); diff --git a/src/basic/mount-util.h b/src/basic/mount-util.h index 32770d68c..56a1f8487 100644 --- a/src/basic/mount-util.h +++ b/src/basic/mount-util.h @@ -37,6 +37,7 @@ 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 mount_move_root(const char *path); #endif // 0