1f08c3bdfSopenharmony_ci// SPDX-License-Identifier: GPL-2.0-or-later 2f08c3bdfSopenharmony_ci/* 3f08c3bdfSopenharmony_ci * Copyright (c) 2020 Linaro Limited. All rights reserved. 4f08c3bdfSopenharmony_ci * Author: Viresh Kumar <viresh.kumar@linaro.org> 5f08c3bdfSopenharmony_ci */ 6f08c3bdfSopenharmony_ci 7f08c3bdfSopenharmony_ci#ifndef LAPI_OPENAT2_H__ 8f08c3bdfSopenharmony_ci#define LAPI_OPENAT2_H__ 9f08c3bdfSopenharmony_ci 10f08c3bdfSopenharmony_ci#include <sys/syscall.h> 11f08c3bdfSopenharmony_ci#include <linux/types.h> 12f08c3bdfSopenharmony_ci 13f08c3bdfSopenharmony_ci#include "lapi/syscalls.h" 14f08c3bdfSopenharmony_ci 15f08c3bdfSopenharmony_ci#include "config.h" 16f08c3bdfSopenharmony_ci 17f08c3bdfSopenharmony_ci#ifndef HAVE_OPENAT2 18f08c3bdfSopenharmony_ci/* 19f08c3bdfSopenharmony_ci * Arguments for how openat2(2) should open the target path. If only @flags and 20f08c3bdfSopenharmony_ci * @mode are non-zero, then openat2(2) operates very similarly to openat(2). 21f08c3bdfSopenharmony_ci * 22f08c3bdfSopenharmony_ci * However, unlike openat(2), unknown or invalid bits in @flags result in 23f08c3bdfSopenharmony_ci * -EINVAL rather than being silently ignored. @mode must be zero unless one of 24f08c3bdfSopenharmony_ci * {O_CREAT, O_TMPFILE} are set. 25f08c3bdfSopenharmony_ci * 26f08c3bdfSopenharmony_ci * @flags: O_* flags. 27f08c3bdfSopenharmony_ci * @mode: O_CREAT/O_TMPFILE file mode. 28f08c3bdfSopenharmony_ci * @resolve: RESOLVE_* flags. 29f08c3bdfSopenharmony_ci */ 30f08c3bdfSopenharmony_cistruct open_how { 31f08c3bdfSopenharmony_ci uint64_t flags; 32f08c3bdfSopenharmony_ci uint64_t mode; 33f08c3bdfSopenharmony_ci uint64_t resolve; 34f08c3bdfSopenharmony_ci}; 35f08c3bdfSopenharmony_ci 36f08c3bdfSopenharmony_ci/* how->resolve flags for openat2(2). */ 37f08c3bdfSopenharmony_ci#define RESOLVE_NO_XDEV 0x01 /* Block mount-point crossings 38f08c3bdfSopenharmony_ci (includes bind-mounts). */ 39f08c3bdfSopenharmony_ci#define RESOLVE_NO_MAGICLINKS 0x02 /* Block traversal through procfs-style 40f08c3bdfSopenharmony_ci "magic-links". */ 41f08c3bdfSopenharmony_ci#define RESOLVE_NO_SYMLINKS 0x04 /* Block traversal through all symlinks 42f08c3bdfSopenharmony_ci (implies OEXT_NO_MAGICLINKS) */ 43f08c3bdfSopenharmony_ci#define RESOLVE_BENEATH 0x08 /* Block "lexical" trickery like 44f08c3bdfSopenharmony_ci "..", symlinks, and absolute 45f08c3bdfSopenharmony_ci paths which escape the dirfd. */ 46f08c3bdfSopenharmony_ci#define RESOLVE_IN_ROOT 0x10 /* Make all jumps to "/" and ".." 47f08c3bdfSopenharmony_ci be scoped inside the dirfd 48f08c3bdfSopenharmony_ci (similar to chroot(2)). */ 49f08c3bdfSopenharmony_ci 50f08c3bdfSopenharmony_cistatic inline int openat2(int dfd, const char *pathname, 51f08c3bdfSopenharmony_ci struct open_how *how, size_t size) 52f08c3bdfSopenharmony_ci{ 53f08c3bdfSopenharmony_ci return tst_syscall(__NR_openat2, dfd, pathname, how, size); 54f08c3bdfSopenharmony_ci} 55f08c3bdfSopenharmony_ci#endif 56f08c3bdfSopenharmony_ci 57f08c3bdfSopenharmony_cistruct open_how_pad { 58f08c3bdfSopenharmony_ci /* how should be kept as the first entry here */ 59f08c3bdfSopenharmony_ci struct open_how how; 60f08c3bdfSopenharmony_ci uint64_t pad; 61f08c3bdfSopenharmony_ci}; 62f08c3bdfSopenharmony_ci 63f08c3bdfSopenharmony_cistatic inline void openat2_supported_by_kernel(void) 64f08c3bdfSopenharmony_ci{ 65f08c3bdfSopenharmony_ci long ret; 66f08c3bdfSopenharmony_ci 67f08c3bdfSopenharmony_ci if ((tst_kvercmp(5, 6, 0)) < 0) { 68f08c3bdfSopenharmony_ci /* Check if the syscall is backported on an older kernel */ 69f08c3bdfSopenharmony_ci ret = syscall(__NR_openat2, -1, NULL, NULL, 0); 70f08c3bdfSopenharmony_ci if (ret == -1 && errno == ENOSYS) 71f08c3bdfSopenharmony_ci tst_brk(TCONF, "Test not supported on kernel version < v5.6"); 72f08c3bdfSopenharmony_ci } 73f08c3bdfSopenharmony_ci} 74f08c3bdfSopenharmony_ci 75f08c3bdfSopenharmony_ci#endif /* LAPI_OPENAT2_H__ */ 76