From: Christian Brauner Date: Sun, 7 Feb 2021 15:19:36 +0000 (+0100) Subject: mount_utils: add locked flag helpers X-Git-Tag: lxc-5.0.0~296^2~11 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=ac11febd37494a6aea082bae504b53f053a76a45;p=thirdparty%2Flxc.git mount_utils: add locked flag helpers Signed-off-by: Christian Brauner --- diff --git a/configure.ac b/configure.ac index 60d7a91e6..31176702e 100644 --- a/configure.ac +++ b/configure.ac @@ -644,7 +644,7 @@ AC_CHECK_HEADER([ifaddrs.h], AC_HEADER_MAJOR # Check for some syscalls functions -AC_CHECK_FUNCS([setns pivot_root sethostname unshare rand_r confstr faccessat gettid memfd_create move_mount open_tree execveat clone3 fsopen fspick fsconfig fsmount, openat2, close_range]) +AC_CHECK_FUNCS([setns pivot_root sethostname unshare rand_r confstr faccessat gettid memfd_create move_mount open_tree execveat clone3 fsopen fspick fsconfig fsmount, openat2, close_range, statvfs]) AC_CHECK_TYPES([struct open_how], [], [], [[#include ]]) AC_CHECK_TYPES([struct clone_args], [], [], [[#include ]]) AC_CHECK_MEMBERS([struct clone_args.set_tid],[],[],[[#include ]]) @@ -684,7 +684,6 @@ fi # Check for some functions AC_CHECK_LIB(pthread, main) -AC_CHECK_FUNCS(statvfs) AC_CHECK_LIB(util, openpty) AC_CHECK_FUNCS([hasmntopt setmntent endmntent utmpxname]) AC_CHECK_FUNCS([getgrgid_r], diff --git a/src/lxc/conf.c b/src/lxc/conf.c index 095c94bb0..4fcb9f102 100644 --- a/src/lxc/conf.c +++ b/src/lxc/conf.c @@ -529,55 +529,6 @@ int pin_rootfs(const char *rootfs) return fd; } -/* If we are asking to remount something, make sure that any NOEXEC etc are - * honored. - */ -unsigned long add_required_remount_flags(const char *s, const char *d, - unsigned long flags) -{ -#ifdef HAVE_STATVFS - int ret; - struct statvfs sb; - unsigned long required_flags = 0; - - if (!s) - s = d; - - if (!s) - return flags; - - ret = statvfs(s, &sb); - if (ret < 0) - return flags; - - if (flags & MS_REMOUNT) { - if (sb.f_flag & MS_NOSUID) - required_flags |= MS_NOSUID; - if (sb.f_flag & MS_NODEV) - required_flags |= MS_NODEV; - if (sb.f_flag & MS_RDONLY) - required_flags |= MS_RDONLY; - if (sb.f_flag & MS_NOEXEC) - required_flags |= MS_NOEXEC; - } - - if (sb.f_flag & MS_NOATIME) - required_flags |= MS_NOATIME; - if (sb.f_flag & MS_NODIRATIME) - required_flags |= MS_NODIRATIME; - if (sb.f_flag & MS_LAZYTIME) - required_flags |= MS_LAZYTIME; - if (sb.f_flag & MS_RELATIME) - required_flags |= MS_RELATIME; - if (sb.f_flag & MS_STRICTATIME) - required_flags |= MS_STRICTATIME; - - return flags | required_flags; -#else - return flags; -#endif -} - static int add_shmount_to_list(struct lxc_conf *conf) { char new_mount[PATH_MAX]; diff --git a/src/lxc/conf.h b/src/lxc/conf.h index 9dae088e6..489b955cd 100644 --- a/src/lxc/conf.h +++ b/src/lxc/conf.h @@ -516,8 +516,6 @@ __hidden extern void turn_into_dependent_mounts(void); __hidden extern void suggest_default_idmap(void); __hidden extern FILE *make_anonymous_mount_file(struct lxc_list *mount, bool include_nesting_helpers); __hidden extern struct lxc_list *sort_cgroup_settings(struct lxc_list *cgroup_settings); -__hidden extern unsigned long add_required_remount_flags(const char *s, const char *d, - unsigned long flags); __hidden extern int run_script(const char *name, const char *section, const char *script, ...); __hidden extern int run_script_argv(const char *name, unsigned int hook_version, const char *section, const char *script, const char *hookname, char **argsin); diff --git a/src/lxc/mount_utils.c b/src/lxc/mount_utils.c index c72a1d677..78e50ecac 100644 --- a/src/lxc/mount_utils.c +++ b/src/lxc/mount_utils.c @@ -11,6 +11,7 @@ #include #include +#include "file_utils.h" #include "log.h" #include "macro.h" #include "memory_utils.h" @@ -18,6 +19,10 @@ #include "syscall_numbers.h" #include "syscall_wrappers.h" +#ifdef HAVE_STATVFS +#include +#endif + lxc_log_define(mount_utils, lxc); int mnt_attributes_new(unsigned int old_flags, unsigned int *new_flags) @@ -284,3 +289,152 @@ int fd_bind_mount(int dfd_from, const char *path_from, TRACE("Attach detached mount %d to filesystem at %d", fd_tree_from, fd_to); return 0; } + +int calc_remount_flags_new(int dfd_from, const char *path_from, + __u64 o_flags_from, __u64 resolve_flags_from, + bool remount, unsigned long cur_flags, + unsigned int *new_flags) +{ +#ifdef HAVE_STATVFS + __do_close int fd_from = -EBADF; + unsigned int new_required_flags = 0; + int ret; + struct statvfs sb; + + fd_from = open_at(dfd_from, path_from, o_flags_from, resolve_flags_from, 0); + if (fd_from < 0) + return log_error_errno(-errno, errno, "Failed to open %d(%s)", dfd_from, maybe_empty(path_from)); + + ret = fstatvfs(dfd_from, &sb); + if (ret < 0) + return log_error_errno(-errno, errno, "Failed to retrieve mount information from %d(%s)", fd_from, maybe_empty(path_from)); + + if (remount) { + if (sb.f_flag & MS_NOSUID) + new_required_flags |= MOUNT_ATTR_NOSUID; + + if (sb.f_flag & MS_NODEV) + new_required_flags |= MOUNT_ATTR_NODEV; + + if (sb.f_flag & MS_RDONLY) + new_required_flags |= MOUNT_ATTR_RDONLY; + + if (sb.f_flag & MS_NOEXEC) + new_required_flags |= MOUNT_ATTR_NOEXEC; + } + + if (sb.f_flag & MS_NOATIME) + new_required_flags |= MOUNT_ATTR_NOATIME; + + if (sb.f_flag & MS_NODIRATIME) + new_required_flags |= MOUNT_ATTR_NODIRATIME; + + if (sb.f_flag & MS_RELATIME) + new_required_flags |= MOUNT_ATTR_RELATIME; + + if (sb.f_flag & MS_STRICTATIME) + new_required_flags |= MOUNT_ATTR_STRICTATIME; + + *new_flags = (cur_flags | new_required_flags); +#endif + return 0; +} + +int calc_remount_flags_old(int dfd_from, const char *path_from, + __u64 o_flags_from, __u64 resolve_flags_from, + bool remount, unsigned long cur_flags, + unsigned int *old_flags) +{ +#ifdef HAVE_STATVFS + __do_close int fd_from = -EBADF; + unsigned int old_required_flags = 0; + int ret; + struct statvfs sb; + + fd_from = open_at(dfd_from, path_from, o_flags_from, resolve_flags_from, 0); + if (fd_from < 0) + return log_error_errno(-errno, errno, "Failed to open %d(%s)", dfd_from, maybe_empty(path_from)); + + ret = fstatvfs(dfd_from, &sb); + if (ret < 0) + return log_error_errno(-errno, errno, "Failed to retrieve mount information from %d(%s)", fd_from, maybe_empty(path_from)); + + if (remount) { + if (sb.f_flag & MS_NOSUID) + old_required_flags |= MS_NOSUID; + + if (sb.f_flag & MS_NODEV) + old_required_flags |= MS_NODEV; + + if (sb.f_flag & MS_RDONLY) + old_required_flags |= MS_RDONLY; + + if (sb.f_flag & MS_NOEXEC) + old_required_flags |= MS_NOEXEC; + } + + if (sb.f_flag & MS_NOATIME) + old_required_flags |= MS_NOATIME; + + if (sb.f_flag & MS_NODIRATIME) + old_required_flags |= MS_NODIRATIME; + + if (sb.f_flag & MS_RELATIME) + old_required_flags |= MS_RELATIME; + + if (sb.f_flag & MS_STRICTATIME) + old_required_flags |= MS_STRICTATIME; + + *old_flags = (cur_flags | old_required_flags); +#endif + return 0; +} + +/* If we are asking to remount something, make sure that any NOEXEC etc are + * honored. + */ +unsigned long add_required_remount_flags(const char *s, const char *d, + unsigned long flags) +{ +#ifdef HAVE_STATVFS + int ret; + struct statvfs sb; + unsigned long required_flags = 0; + + if (!s) + s = d; + + if (!s) + return flags; + + ret = statvfs(s, &sb); + if (ret < 0) + return flags; + + if (flags & MS_REMOUNT) { + if (sb.f_flag & MS_NOSUID) + required_flags |= MS_NOSUID; + if (sb.f_flag & MS_NODEV) + required_flags |= MS_NODEV; + if (sb.f_flag & MS_RDONLY) + required_flags |= MS_RDONLY; + if (sb.f_flag & MS_NOEXEC) + required_flags |= MS_NOEXEC; + } + + if (sb.f_flag & MS_NOATIME) + required_flags |= MS_NOATIME; + if (sb.f_flag & MS_NODIRATIME) + required_flags |= MS_NODIRATIME; + if (sb.f_flag & MS_LAZYTIME) + required_flags |= MS_LAZYTIME; + if (sb.f_flag & MS_RELATIME) + required_flags |= MS_RELATIME; + if (sb.f_flag & MS_STRICTATIME) + required_flags |= MS_STRICTATIME; + + return flags | required_flags; +#else + return flags; +#endif +} diff --git a/src/lxc/mount_utils.h b/src/lxc/mount_utils.h index 54c941e13..9e28eccf4 100644 --- a/src/lxc/mount_utils.h +++ b/src/lxc/mount_utils.h @@ -207,4 +207,20 @@ static inline bool new_mount_api(void) return supported == 1; } +__hidden extern int calc_remount_flags_new(int dfd_from, const char *path_from, + __u64 o_flags_from, + __u64 resolve_flags_from, + bool remount, unsigned long cur_flags, + unsigned int *new_flags); + +__hidden extern int calc_remount_flags_old(int dfd_from, const char *path_from, + __u64 o_flags_from, + __u64 resolve_flags_from, + bool remount, unsigned long cur_flags, + unsigned int *old_flags); + +__hidden extern unsigned long add_required_remount_flags(const char *s, + const char *d, + unsigned long flags); + #endif /* __LXC_MOUNT_UTILS_H */ diff --git a/src/lxc/storage/dir.c b/src/lxc/storage/dir.c index 18a10a42f..c1ec5d17d 100644 --- a/src/lxc/storage/dir.c +++ b/src/lxc/storage/dir.c @@ -11,6 +11,7 @@ #include "log.h" #include "macro.h" #include "memory_utils.h" +#include "mount_utils.h" #include "storage.h" #include "utils.h"