]> git.proxmox.com Git - mirror_lxc.git/commitdiff
tree-wide: rework mount api support checks
authorChristian Brauner <christian.brauner@ubuntu.com>
Thu, 11 Feb 2021 13:51:46 +0000 (14:51 +0100)
committerChristian Brauner <christian.brauner@ubuntu.com>
Thu, 11 Feb 2021 13:57:51 +0000 (14:57 +0100)
Signed-off-by: Christian Brauner <christian.brauner@ubuntu.com>
src/lxc/cgroups/cgfsng.c
src/lxc/conf.c
src/lxc/mount_utils.c
src/lxc/mount_utils.h

index 44b9d7c0080728567954bb2bf92297bed11bddfc..aff6bc8521fcb2251afddb33221b2847fac19845 100644 (file)
@@ -1800,7 +1800,7 @@ static int __cg_mount_direct(int type, struct hierarchy *h,
                fstype = "cgroup";
        }
 
-       if (new_mount_api()) {
+       if (can_use_mount_api()) {
                fd_fs = fs_prepare(fstype, -EBADF, "", 0, 0);
                if (fd_fs < 0)
                        return log_error_errno(-errno, errno, "Failed to prepare filesystem context for %s", fstype);
@@ -1946,7 +1946,7 @@ __cgfsng_ops static bool cgfsng_mount(struct cgroup_ops *ops,
         * relying on RESOLVE_BENEATH so we need to skip the leading "/" in the
         * DEFAULT_CGROUP_MOUNTPOINT define.
         */
-       if (new_mount_api()) {
+       if (can_use_mount_api()) {
                fd_fs = fs_prepare("tmpfs", -EBADF, "", 0, 0);
                if (fd_fs < 0)
                        return log_error_errno(-errno, errno, "Failed to create new filesystem context for tmpfs");
index 4cf91a7ee0e9514695a7f06dde9e9d5f1f8e65ce..5a69d3d98b9626c99634276f8ab7a384a80bcae1 100644 (file)
@@ -844,7 +844,7 @@ static int lxc_setup_ttys(struct lxc_conf *conf)
                                                       "Failed to unlink %d(%s)",
                                                       rootfs->dfd_dev, tty_name);
 
-                       if (new_mount_api()) {
+                       if (can_use_mount_api()) {
                                ret = fd_bind_mount(tty->pty, "",
                                                    PROTECT_OPATH_FILE,
                                                    PROTECT_LOOKUP_BENEATH_XDEV,
@@ -881,7 +881,7 @@ static int lxc_setup_ttys(struct lxc_conf *conf)
                                                       "Failed to create tty mount target %d(%s)",
                                                       rootfs->dfd_dev, rootfs->buf);
 
-                       if (new_mount_api()) {
+                       if (can_use_mount_api()) {
                                ret = fd_bind_mount(tty->pty, "",
                                                    PROTECT_OPATH_FILE,
                                                    PROTECT_LOOKUP_BENEATH_XDEV,
@@ -1074,7 +1074,7 @@ static int mount_autodev(const char *name, const struct lxc_rootfs *rootfs,
                goto reset_umask;
        }
 
-       if (new_mount_api()) {
+       if (can_use_mount_api()) {
                fd_fs = fs_prepare("tmpfs", -EBADF, "", 0, 0);
                if (fd_fs < 0)
                        return log_error_errno(-errno, errno, "Failed to prepare filesystem context for tmpfs");
@@ -1216,7 +1216,7 @@ static int lxc_fill_autodev(struct lxc_rootfs *rootfs)
                if (ret < 0)
                        return ret_errno(EIO);
 
-               if (new_mount_api()) {
+               if (can_use_mount_api()) {
                        ret = fd_bind_mount(rootfs->dfd_host, rootfs->buf,
                                            PROTECT_OPATH_FILE,
                                            PROTECT_LOOKUP_BENEATH_XDEV,
@@ -1716,7 +1716,7 @@ static int lxc_setup_dev_console(struct lxc_rootfs *rootfs,
        if (ret < 0)
                return log_error_errno(-errno, errno, "Failed to set mode \"0%o\" to \"%s\"", S_IXUSR | S_IXGRP, console->name);
 
-       if (new_mount_api()) {
+       if (can_use_mount_api()) {
                ret = lxc_bind_mount_console(console, rootfs->dfd_dev, "console");
        } else {
                ret = strnprintf(rootfs->buf, sizeof(rootfs->buf), "%s/dev/console", rootfs_path);
@@ -1779,7 +1779,7 @@ static int lxc_setup_ttydir_console(struct lxc_rootfs *rootfs,
                return log_error_errno(-errno, errno, "Failed to set mode \"0%o\" to \"%s\"", S_IXUSR | S_IXGRP, console->name);
 
        /* bind mount console->name to '/dev/<ttydir>/console' */
-       if (new_mount_api()) {
+       if (can_use_mount_api()) {
                ret = strnprintf(rootfs->buf, sizeof(rootfs->buf), "%s/console", ttydir);
                if (ret < 0)
                        return ret;
@@ -1793,7 +1793,7 @@ static int lxc_setup_ttydir_console(struct lxc_rootfs *rootfs,
        DEBUG("Mounted \"%s\" onto \"%s\"", console->name, lxcpath);
 
        /* bind mount '/dev/<ttydir>/console'  to '/dev/console'  */
-       if (new_mount_api()) {
+       if (can_use_mount_api()) {
                ret = fd_bind_mount(rootfs->dfd_dev, rootfs->buf,
                                    PROTECT_OPATH_FILE, PROTECT_LOOKUP_BENEATH_XDEV,
                                    rootfs->dfd_dev, "console",
index 5132ea226e1137ee9c7bb7aec866058a737fd6d7..c0d5a453585e93c00864b16f87b17745d0b62231 100644 (file)
@@ -438,3 +438,53 @@ unsigned long add_required_remount_flags(const char *s, const char *d,
        return flags;
 #endif
 }
+
+bool can_use_mount_api(void)
+{
+       static int supported = -1;
+
+       if (supported == -1) {
+               __do_close int fd = -EBADF;
+
+               fd = openat2(-EBADF, "", NULL, 0);
+               if (fd > 0 || errno == ENOSYS) {
+                       supported = 0;
+                       return false;
+               }
+
+               fd = fsmount(-EBADF, 0, 0);
+               if (fd > 0 || errno == ENOSYS) {
+                       supported = 0;
+                       return false;
+               }
+
+               fd = fsconfig(-EBADF, -EINVAL, NULL, NULL, 0);
+               if (fd > 0 || errno == ENOSYS) {
+                       supported = 0;
+                       return false;
+               }
+
+               fd = fsopen(NULL, 0);
+               if (fd > 0 || errno == ENOSYS) {
+                       supported = 0;
+                       return false;
+               }
+
+               fd = move_mount(-EBADF, NULL, -EBADF, NULL, 0);
+               if (fd > 0 || errno == ENOSYS) {
+                       supported = 0;
+                       return false;
+               }
+
+               fd = open_tree(-EBADF, NULL, 0);
+               if (fd > 0 || errno == ENOSYS) {
+                       supported = 0;
+                       return false;
+               }
+
+               supported = 1;
+               TRACE("Kernel supports mount api");
+       }
+
+       return supported == 1;
+}
index 9e28eccf4e2587f0d43be99053b1f2a76df04b45..d38581d9b11c9d489c2b84e6855ac06403811424 100644 (file)
@@ -185,28 +185,6 @@ __hidden extern int fd_bind_mount(int dfd_from, const char *path_from,
                                  __u64 o_flags_to, __u64 resolve_flags_to,
                                  unsigned int attr_flags, bool recursive);
 
-/*
- * We use openat2() as indicator whether or not the new mount api is supported.
- * First, because openat2() has been introduced after all syscalls from the new
- * mount api we currently use and second because our hardened mount logic
- * relies on openat2() to safely resolve paths.
- */
-static inline bool new_mount_api(void)
-{
-       __do_close int fd = -EBADF;
-       static int supported = -1;
-
-       if (supported == -1) {
-               fd = openat2(-EBADF, "", NULL, 0);
-               if (fd < 0 && errno != ENOSYS)
-                       supported = 1;
-               else
-                       supported = 0;
-       }
-
-       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,
@@ -223,4 +201,6 @@ __hidden extern unsigned long add_required_remount_flags(const char *s,
                                                         const char *d,
                                                         unsigned long flags);
 
+__hidden extern bool can_use_mount_api(void);
+
 #endif /* __LXC_MOUNT_UTILS_H */