]> git.ipfire.org Git - thirdparty/lxc.git/commitdiff
mount_utils: introduce mount_at()
authorChristian Brauner <christian.brauner@ubuntu.com>
Mon, 2 Aug 2021 13:30:03 +0000 (15:30 +0200)
committerChristian Brauner <christian.brauner@ubuntu.com>
Mon, 2 Aug 2021 13:30:03 +0000 (15:30 +0200)
Signed-off-by: Christian Brauner <christian.brauner@ubuntu.com>
src/lxc/conf.c
src/lxc/mount_utils.c
src/lxc/mount_utils.h

index a20d1f073c4f2a51cdb408e52caa63e1beef59df..8ea36174b78d696abfcec6e229d7955f7113b23a 100644 (file)
@@ -1742,7 +1742,9 @@ static int lxc_setup_devpts_child(struct lxc_handler *handler)
 
                for (ret = -1, opts = mntopt_sets; opts && *opts; opts++) {
                        /* mount new devpts instance */
-                       ret = mount_beneath_fd(rootfs->dfd_dev, "", "pts", "devpts", MS_NOSUID | MS_NOEXEC, *opts);
+                       ret = mount_at(rootfs->dfd_dev, "", 0,
+                                      rootfs->dfd_dev, "pts", PROTECT_LOOKUP_BENEATH,
+                                      "devpts", MS_NOSUID | MS_NOEXEC, *opts);
                        if (ret == 0)
                                break;
                }
@@ -1775,7 +1777,9 @@ static int lxc_setup_devpts_child(struct lxc_handler *handler)
        DEBUG("Created \"/dev/ptmx\" file as bind mount target");
 
        /* Main option: use a bind-mount to please AppArmor  */
-       ret = mount_beneath_fd(rootfs->dfd_dev, "pts/ptmx", "ptmx", NULL, MS_BIND, NULL);
+       ret = mount_at(rootfs->dfd_dev, "pts/ptmx", (PROTECT_LOOKUP_BENEATH_WITH_SYMLINKS & ~RESOLVE_NO_XDEV),
+                      rootfs->dfd_dev, "ptmx", (PROTECT_LOOKUP_BENEATH_WITH_SYMLINKS & ~RESOLVE_NO_XDEV),
+                      NULL, MS_BIND, NULL);
        if (!ret)
                return log_debug(0, "Bind mounted \"/dev/pts/ptmx\" to \"/dev/ptmx\"");
        else
index 77498bbf30fc5bd41aca60a4640cbd822e46bc03..783503aae8d27193b1589373f2ac558a431b7cb7 100644 (file)
@@ -606,66 +606,56 @@ bool can_use_bind_mounts(void)
        return supported == 1;
 }
 
-int mount_beneath_fd(int fd, const char *source, const char *target,
-                    const char *fs_name, unsigned int flags, const void *data)
+int mount_at(int dfd_from, const char *path_from, __u64 resolve_flags_from,
+            int dfd_to, const char *path_to, __u64 resolve_flags_to,
+            const char *fs_name, unsigned int flags, const void *data)
 {
-       int ret;
-       char buf_source[PATH_MAX], buf_target[PATH_MAX];
+       __do_close int __fd_from = -EBADF, __fd_to = -EBADF;
+       char *from = NULL, *to = NULL;
+       int fd_from, fd_to, ret;
+       char buf_from[LXC_PROC_SELF_FD_LEN], buf_to[LXC_PROC_SELF_FD_LEN];
 
-       if (abspath(source) || abspath(target))
+       if (dfd_from < 0 && !abspath(path_from))
                return ret_errno(EINVAL);
 
-       ret = strnprintf(buf_target, sizeof(buf_target), "/proc/self/fd/%d/%s", fd, target);
-       if (ret < 0)
-               return syserror("Failed to create path");
+       if (dfd_to < 0 && !abspath(path_to))
+               return ret_errno(EINVAL);
 
-       if (is_empty_string(source)) {
-               ret = mount(fs_name ?: "", buf_target, fs_name, flags, data);
+       if (!is_empty_string(path_from)) {
+               __fd_from = open_at(dfd_from, path_from, PROTECT_OPATH_FILE, resolve_flags_from, 0);
+               if (__fd_from < 0)
+                       return -errno;
+               fd_from = __fd_from;
        } else {
-               ret = strnprintf(buf_source, sizeof(buf_source), "/proc/self/fd/%d/%s", fd, source);
+               fd_from = dfd_from;
+       }
+       if (fd_from >= 0) {
+               ret = strnprintf(buf_from, sizeof(buf_from), "/proc/self/fd/%d", fd_from);
                if (ret < 0)
                        return syserror("Failed to create path");
-
-               source = buf_source;
-               ret = mount(source, buf_target, fs_name, flags, data);
+               from = buf_from;
        }
-       if (ret < 0)
-               return syserror("Failed to mount \"%s\" to \"%s\"", source, buf_target);
 
-       TRACE("Mounted \"%s\" to \"%s\"", source, buf_target);
-       return 0;
-}
-
-int mount_fd(int fd_source, int fd_target, const char *fs_name,
-            unsigned int flags, const void *data)
-{
-       int ret;
-       char buf_source[LXC_PROC_PID_FD_LEN], buf_target[LXC_PROC_PID_FD_LEN];
-       char *source = buf_source, *target = buf_target;
-
-       if (fd_source < 0) {
-               source = NULL;
+       if (!is_empty_string(path_to)) {
+               __fd_to = open_at(dfd_to, path_to, PROTECT_OPATH_FILE, resolve_flags_to, 0);
+               if (__fd_to < 0)
+                       return -errno;
+               fd_to = __fd_to;
        } else {
-               ret = strnprintf(buf_source, sizeof(buf_source),
-                                "/proc/self/fd/%d", fd_source);
-               if (ret < 0)
-                       return ret;
+               fd_to = dfd_to;
        }
-
-       if (fd_target < 0) {
-               target = NULL;
-       } else {
-               ret = strnprintf(buf_target, sizeof(buf_target),
-                                "/proc/self/fd/%d", fd_target);
+       if (fd_to >= 0) {
+               ret = strnprintf(buf_to, sizeof(buf_to), "/proc/self/fd/%d", fd_to);
                if (ret < 0)
-                       return ret;
+                       return syserror("Failed to create path");
+               to = buf_to;
        }
 
-       ret = mount(source, target, "none", MS_BIND, 0);
+       ret = mount(from ?: fs_name, to, fs_name, flags, data);
        if (ret < 0)
                return syserror("Failed to mount \"%s\" to \"%s\"",
-                               maybe_empty(source), maybe_empty(target));
+                               maybe_empty(from), maybe_empty(to));
 
-       TRACE("Mounted \"%s\" to \"%s\"", maybe_empty(source), maybe_empty(target));
+       TRACE("Mounted \"%s\" to \"%s\"", maybe_empty(from), maybe_empty(to));
        return 0;
 }
index 4caf34b2fbaf041737fff9e261675fc55856a026..6fed1a0a9e25defee2409f81120fa37013604b90 100644 (file)
@@ -221,10 +221,15 @@ __hidden extern unsigned long add_required_remount_flags(const char *s,
 
 __hidden extern bool can_use_mount_api(void);
 __hidden extern bool can_use_bind_mounts(void);
-__hidden extern int mount_beneath_fd(int fd, const char *source,
-                                    const char *target, const char *fs_name,
-                                    unsigned int flags, const void *data);
-__hidden extern int mount_fd(int fd_source, int fd_target, const char *fs_name,
-                            unsigned int flags, const void *data);
+__hidden extern int mount_at(int dfd_from, const char *path_from,
+                            __u64 resolve_flags_from, int dfd_to,
+                            const char *path_to, __u64 resolve_flags_to,
+                            const char *fs_name, unsigned int flags,
+                            const void *data);
+static inline int mount_fd(int fd_from, int fd_to, const char *fs_name,
+                          unsigned int flags, const void *data)
+{
+       return mount_at(fd_from, "", 0, fd_to, "", 0, fs_name, flags, data);
+}
 
 #endif /* __LXC_MOUNT_UTILS_H */