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 <linux/openat2.h>]])
AC_CHECK_TYPES([struct clone_args], [], [], [[#include <linux/sched.h>]])
AC_CHECK_MEMBERS([struct clone_args.set_tid],[],[],[[#include <linux/sched.h>]])
AC_CHECK_MEMBERS([struct clone_args.cgroup],[],[],[[#include <linux/sched.h>]])
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);
#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 */
#include <unistd.h>
#include "config.h"
+#include "macro.h"
#include "syscall_numbers.h"
#ifdef HAVE_LINUX_MEMFD_H
#include <sys/signalfd.h>
#endif
+#ifdef HAVE_STRUCT_OPEN_HOW
+#include <linux/openat2.h>
+#endif
+
typedef int32_t key_serial_t;
#if !HAVE_KEYCTL
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 */