From 2b0c8106175f35b8347a508f55845a3792e717b8 Mon Sep 17 00:00:00 2001 From: Christian Brauner Date: Sun, 9 Aug 2020 12:48:02 +0200 Subject: [PATCH] syscalls: add openat2() Signed-off-by: Christian Brauner --- configure.ac | 3 +- src/lxc/conf.c | 2 +- src/lxc/syscall_numbers.h | 20 ++++++++++++ src/lxc/syscall_wrappers.h | 62 ++++++++++++++++++++++++++++++++++++++ 4 files changed, 85 insertions(+), 2 deletions(-) diff --git a/configure.ac b/configure.ac index 70099e3ad..f58487f5d 100644 --- a/configure.ac +++ b/configure.ac @@ -622,7 +622,8 @@ AC_CHECK_HEADER([ifaddrs.h], AC_HEADER_MAJOR # Check for some syscalls functions -AC_CHECK_FUNCS([setns pivot_root sethostname unshare rand_r confstr faccessat gettid memfd_create move_mount open_tree execveat clone3 fsopen fspick fsconfig fsmount]) +AC_CHECK_FUNCS([setns pivot_root sethostname unshare rand_r confstr faccessat gettid memfd_create move_mount open_tree execveat clone3 fsopen fspick fsconfig fsmount, openat2]) +AC_CHECK_TYPES([struct open_how], [], [], [[#include ]]) AC_CHECK_TYPES([struct clone_args], [], [], [[#include ]]) AC_CHECK_MEMBERS([struct clone_args.set_tid],[],[],[[#include ]]) AC_CHECK_MEMBERS([struct clone_args.cgroup],[],[],[[#include ]]) diff --git a/src/lxc/conf.c b/src/lxc/conf.c index 36a2309a4..2e513d1cc 100644 --- a/src/lxc/conf.c +++ b/src/lxc/conf.c @@ -1077,7 +1077,7 @@ static int mount_autodev(const char *name, const struct lxc_rootfs *rootfs, goto reset_umask; } - ret = safe_mount("none", path, "tmpfs", 0, mount_options, + ret = safe_mount("none", "dev", "tmpfs", 0, mount_options, rootfs->path ? rootfs->mount : NULL ); if (ret < 0) { SYSERROR("Failed to mount tmpfs on \"%s\"", path); diff --git a/src/lxc/syscall_numbers.h b/src/lxc/syscall_numbers.h index 72e4ffe46..8305173d6 100644 --- a/src/lxc/syscall_numbers.h +++ b/src/lxc/syscall_numbers.h @@ -640,4 +640,24 @@ #endif #endif +#ifndef __NR_openat2 + #if defined __alpha__ + #define __NR_openat2 547 + #elif defined _MIPS_SIM + #if _MIPS_SIM == _MIPS_SIM_ABI32 /* o32 */ + #define __NR_openat2 4437 + #endif + #if _MIPS_SIM == _MIPS_SIM_NABI32 /* n32 */ + #define __NR_openat2 6437 + #endif + #if _MIPS_SIM == _MIPS_SIM_ABI64 /* n64 */ + #define __NR_openat2 5437 + #endif + #elif defined __ia64__ + #define __NR_openat2 (437 + 1024) + #else + #define __NR_openat2 437 + #endif +#endif + #endif /* __LXC_SYSCALL_NUMBERS_H */ diff --git a/src/lxc/syscall_wrappers.h b/src/lxc/syscall_wrappers.h index 6aaa43722..37aa76c28 100644 --- a/src/lxc/syscall_wrappers.h +++ b/src/lxc/syscall_wrappers.h @@ -16,6 +16,7 @@ #include #include "config.h" +#include "macro.h" #include "syscall_numbers.h" #ifdef HAVE_LINUX_MEMFD_H @@ -26,6 +27,10 @@ #include #endif +#ifdef HAVE_STRUCT_OPEN_HOW +#include +#endif + typedef int32_t key_serial_t; #if !HAVE_KEYCTL @@ -203,4 +208,61 @@ static inline int fsmount_lxc(int fs_fd, unsigned int flags, unsigned int attr_f extern int fsmount(int fs_fd, unsigned int flags, unsigned int attr_flags); #endif +/* + * Arguments for how openat2(2) should open the target path. If only @flags and + * @mode are non-zero, then openat2(2) operates very similarly to openat(2). + * + * However, unlike openat(2), unknown or invalid bits in @flags result in + * -EINVAL rather than being silently ignored. @mode must be zero unless one of + * {O_CREAT, O_TMPFILE} are set. + * + * @flags: O_* flags. + * @mode: O_CREAT/O_TMPFILE file mode. + * @resolve: RESOLVE_* flags. + */ +struct lxc_open_how { + __u64 flags; + __u64 mode; + __u64 resolve; +}; + +/* how->resolve flags for openat2(2). */ +#ifndef RESOLVE_NO_XDEV +#define RESOLVE_NO_XDEV 0x01 /* Block mount-point crossings + (includes bind-mounts). */ +#endif + +#ifndef RESOLVE_NO_MAGICLINKS +#define RESOLVE_NO_MAGICLINKS 0x02 /* Block traversal through procfs-style + "magic-links". */ +#endif + +#ifndef RESOLVE_NO_SYMLINKS +#define RESOLVE_NO_SYMLINKS 0x04 /* Block traversal through all symlinks + (implies OEXT_NO_MAGICLINKS) */ +#endif + +#ifndef RESOLVE_BENEATH +#define RESOLVE_BENEATH 0x08 /* Block "lexical" trickery like + "..", symlinks, and absolute + paths which escape the dirfd. */ +#endif + +#ifndef RESOLVE_IN_ROOT +#define RESOLVE_IN_ROOT 0x10 /* Make all jumps to "/" and ".." + be scoped inside the dirfd + (similar to chroot(2)). */ +#endif + +#ifndef HAVE_OPENAT2 +static inline int openat2(int dfd, const char *filename, struct lxc_open_how *how, size_t size) +{ + /* When struct open_how is updated we should update lxc as well. */ +#ifdef HAVE_STRUCT_OPEN_HOW + BUILD_BUG_ON(sizeof(struct lxc_open_how) != sizeof(struct open_how)); +#endif + return syscall(__NR_openat2, dfd, filename, (struct open_how *)how, size); +} +#endif /* HAVE_OPENAT2 */ + #endif /* __LXC_SYSCALL_WRAPPER_H */