]> git.ipfire.org Git - thirdparty/lxc.git/commitdiff
utils: add safe_mount_beneath() based on openat2()
authorChristian Brauner <christian.brauner@ubuntu.com>
Sun, 9 Aug 2020 13:24:26 +0000 (15:24 +0200)
committerChristian Brauner <christian.brauner@ubuntu.com>
Sun, 9 Aug 2020 17:52:30 +0000 (19:52 +0200)
Signed-off-by: Christian Brauner <christian.brauner@ubuntu.com>
src/lxc/utils.c
src/lxc/utils.h

index 39de189afc482207d816944638f1a80b2770caa5..4efed645ff7552ca809e1e4bb272a9eb1d85d265 100644 (file)
@@ -1079,6 +1079,44 @@ out:
        return dirfd;
 }
 
+int safe_mount_beneath(const char *beneath, const char *src, const char *dst, const char *fstype,
+                      unsigned int flags, const void *data)
+{
+       __do_close int beneath_fd = -EBADF, source_fd = -EBADF, target_fd = -EBADF;
+       const char *path = beneath ? beneath : "/";
+       struct lxc_open_how how = {
+               .flags          = O_RDONLY | O_CLOEXEC | O_PATH,
+               .resolve        = RESOLVE_NO_XDEV | RESOLVE_NO_SYMLINKS | RESOLVE_NO_MAGICLINKS | RESOLVE_BENEATH,
+       };
+       int ret;
+       char src_buf[LXC_PROC_PID_FD_LEN], tgt_buf[LXC_PROC_PID_FD_LEN];
+
+       beneath_fd = openat(-1, beneath, O_RDONLY | O_CLOEXEC | O_DIRECTORY | O_PATH);
+       if (beneath_fd < 0)
+               return log_error_errno(-errno, errno, "Failed to open %s", path);
+
+       if ((flags & MS_BIND) && src && src[0] != '/') {
+               source_fd = openat2(beneath_fd, src, &how, sizeof(how));
+               if (source_fd < 0)
+                       return -errno;
+               snprintf(src_buf, sizeof(src_buf), "/proc/self/fd/%d", source_fd);
+       } else {
+               src_buf[0] = '\0';
+       }
+
+       target_fd = openat2(beneath_fd, dst, &how, sizeof(how));
+       if (target_fd < 0)
+               return -errno;
+       snprintf(tgt_buf, sizeof(tgt_buf), "/proc/self/fd/%d", target_fd);
+
+       if (!is_empty_string(src_buf))
+               ret = mount(src_buf, tgt_buf, fstype, flags, data);
+       else
+               ret = mount(src, tgt_buf, fstype, flags, data);
+
+       return ret;
+}
+
 /*
  * Safely mount a path into a container, ensuring that the mount target
  * is under the container's @rootfs.  (If @rootfs is NULL, then the container
index 3f9a4091506470daf8ac103cfc55c66631e5bdb2..b0de9d9abc08501c37821ee86e904ffdef7f24cf 100644 (file)
@@ -246,4 +246,7 @@ static inline bool gid_valid(gid_t gid)
 
 __hidden extern bool multiply_overflow(int64_t base, uint64_t mult, int64_t *res);
 
+extern int safe_mount_beneath(const char *beneath, const char *src, const char *dst,
+                             const char *fstype, unsigned int flags, const void *data);
+
 #endif /* __LXC_UTILS_H */