From 65f0afdee28f1f867e48ad68cca2ef7e098bc03e Mon Sep 17 00:00:00 2001 From: Christian Brauner Date: Sun, 9 Aug 2020 15:24:26 +0200 Subject: [PATCH] utils: add safe_mount_beneath() based on openat2() Signed-off-by: Christian Brauner --- src/lxc/utils.c | 38 ++++++++++++++++++++++++++++++++++++++ src/lxc/utils.h | 3 +++ 2 files changed, 41 insertions(+) diff --git a/src/lxc/utils.c b/src/lxc/utils.c index 39de189af..4efed645f 100644 --- a/src/lxc/utils.c +++ b/src/lxc/utils.c @@ -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 diff --git a/src/lxc/utils.h b/src/lxc/utils.h index 3f9a40915..b0de9d9ab 100644 --- a/src/lxc/utils.h +++ b/src/lxc/utils.h @@ -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 */ -- 2.47.2