2
0
mirror of git://github.com/lxc/lxc synced 2025-08-30 23:29:33 +00:00

mount_utils: introduce mount_at()

Signed-off-by: Christian Brauner <christian.brauner@ubuntu.com>
This commit is contained in:
Christian Brauner
2021-08-02 15:30:03 +02:00
parent 1b8f92fe74
commit 8b0ccdaaf3
3 changed files with 50 additions and 51 deletions

View 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

View 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);
fd_to = dfd_to;
}
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;
}
if (fd_target < 0) {
target = NULL;
} else {
ret = strnprintf(buf_target, sizeof(buf_target),
"/proc/self/fd/%d", fd_target);
if (ret < 0)
return ret;
}
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;
}

View 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 */