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);
* 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");
"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,
"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,
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");
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,
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);
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;
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",
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;
+}
__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,
const char *d,
unsigned long flags);
+__hidden extern bool can_use_mount_api(void);
+
#endif /* __LXC_MOUNT_UTILS_H */