1 /* SPDX-License-Identifier: LGPL-2.1+ */
3 #ifndef __LXC_SYSCALL_WRAPPER_H
4 #define __LXC_SYSCALL_WRAPPER_H
8 #include <asm/unistd.h>
10 #include <linux/keyctl.h>
13 #include <sys/prctl.h>
14 #include <sys/syscall.h>
15 #include <sys/types.h>
19 #include "syscall_numbers.h"
21 #ifdef HAVE_LINUX_MEMFD_H
22 #include <linux/memfd.h>
25 #ifdef HAVE_SYS_SIGNALFD_H
26 #include <sys/signalfd.h>
29 #if HAVE_SYS_PERSONALITY_H
30 #include <sys/personality.h>
33 typedef int32_t key_serial_t
;
36 static inline long __keyctl(int cmd
, unsigned long arg2
, unsigned long arg3
,
37 unsigned long arg4
, unsigned long arg5
)
39 return syscall(__NR_keyctl
, cmd
, arg2
, arg3
, arg4
, arg5
);
41 #define keyctl __keyctl
44 #ifndef F_LINUX_SPECIFIC_BASE
45 #define F_LINUX_SPECIFIC_BASE 1024
48 #define F_ADD_SEALS (F_LINUX_SPECIFIC_BASE + 9)
49 #define F_GET_SEALS (F_LINUX_SPECIFIC_BASE + 10)
52 #define F_SEAL_SEAL 0x0001
53 #define F_SEAL_SHRINK 0x0002
54 #define F_SEAL_GROW 0x0004
55 #define F_SEAL_WRITE 0x0008
58 #if !HAVE_MEMFD_CREATE
59 static inline int memfd_create_lxc(const char *name
, unsigned int flags
)
61 return syscall(__NR_memfd_create
, name
, flags
);
63 #define memfd_create memfd_create_lxc
65 extern int memfd_create(const char *name
, unsigned int flags
);
69 static inline int pivot_root(const char *new_root
, const char *put_old
)
71 return syscall(__NR_pivot_root
, new_root
, put_old
);
74 extern int pivot_root(const char *new_root
, const char *put_old
);
77 /* Define sethostname() if missing from the C library */
79 static inline int sethostname(const char *name
, size_t len
)
81 return syscall(__NR_sethostname
, name
, len
);
85 /* Define setns() if missing from the C library */
87 static inline int setns(int fd
, int nstype
)
89 return syscall(__NR_setns
, fd
, nstype
);
93 #if !HAVE_SYS_SIGNALFD_H
94 struct signalfd_siginfo
{
103 uint32_t ssi_overrun
;
114 static inline int signalfd(int fd
, const sigset_t
*mask
, int flags
)
118 retval
= syscall(__NR_signalfd4
, fd
, mask
, _NSIG
/ 8, flags
);
120 if (errno
== ENOSYS
&& flags
== 0)
121 retval
= syscall(__NR_signalfd
, fd
, mask
, _NSIG
/ 8);
128 /* Define unshare() if missing from the C library */
130 static inline int unshare(int flags
)
132 return syscall(__NR_unshare
, flags
);
135 extern int unshare(int);
138 /* Define faccessat() if missing from the C library */
140 static int faccessat(int __fd
, const char *__file
, int __type
, int __flag
)
142 return syscall(__NR_faccessat
, __fd
, __file
, __type
, __flag
);
147 static inline int move_mount_lxc(int from_dfd
, const char *from_pathname
,
148 int to_dfd
, const char *to_pathname
,
151 return syscall(__NR_move_mount
, from_dfd
, from_pathname
, to_dfd
,
154 #define move_mount move_mount_lxc
156 extern int move_mount(int from_dfd
, const char *from_pathname
, int to_dfd
,
157 const char *to_pathname
, unsigned int flags
);
161 static inline int open_tree_lxc(int dfd
, const char *filename
, unsigned int flags
)
163 return syscall(__NR_open_tree
, dfd
, filename
, flags
);
165 #define open_tree open_tree_lxc
167 extern int open_tree(int dfd
, const char *filename
, unsigned int flags
);
171 static inline int fsopen_lxc(const char *fs_name
, unsigned int flags
)
173 return syscall(__NR_fsopen
, fs_name
, flags
);
175 #define fsopen fsopen_lxc
177 extern int fsopen(const char *fs_name
, unsigned int flags
);
181 static inline int fspick_lxc(int dfd
, const char *path
, unsigned int flags
)
183 return syscall(__NR_fspick
, dfd
, path
, flags
);
185 #define fspick fspick_lxc
187 extern int fspick(int dfd
, const char *path
, unsigned int flags
);
191 static inline int fsconfig_lxc(int fd
, unsigned int cmd
, const char *key
, const void *value
, int aux
)
193 return syscall(__NR_fsconfig
, fd
, cmd
, key
, value
, aux
);
195 #define fsconfig fsconfig_lxc
197 extern int fsconfig(int fd
, unsigned int cmd
, const char *key
, const void *value
, int aux
);
201 static inline int fsmount_lxc(int fs_fd
, unsigned int flags
, unsigned int attr_flags
)
203 return syscall(__NR_fsmount
, fs_fd
, flags
, attr_flags
);
205 #define fsmount fsmount_lxc
207 extern int fsmount(int fs_fd
, unsigned int flags
, unsigned int attr_flags
);
213 struct lxc_mount_attr
{
220 #if !HAVE_MOUNT_SETATTR
221 static inline int mount_setattr(int dfd
, const char *path
, unsigned int flags
,
222 struct lxc_mount_attr
*attr
, size_t size
)
224 return syscall(__NR_mount_setattr
, dfd
, path
, flags
, attr
, size
);
229 * Arguments for how openat2(2) should open the target path. If only @flags and
230 * @mode are non-zero, then openat2(2) operates very similarly to openat(2).
232 * However, unlike openat(2), unknown or invalid bits in @flags result in
233 * -EINVAL rather than being silently ignored. @mode must be zero unless one of
234 * {O_CREAT, O_TMPFILE} are set.
237 * @mode: O_CREAT/O_TMPFILE file mode.
238 * @resolve: RESOLVE_* flags.
240 struct lxc_open_how
{
246 /* how->resolve flags for openat2(2). */
247 #ifndef RESOLVE_NO_XDEV
248 #define RESOLVE_NO_XDEV 0x01 /* Block mount-point crossings
249 (includes bind-mounts). */
252 #ifndef RESOLVE_NO_MAGICLINKS
253 #define RESOLVE_NO_MAGICLINKS 0x02 /* Block traversal through procfs-style
257 #ifndef RESOLVE_NO_SYMLINKS
258 #define RESOLVE_NO_SYMLINKS 0x04 /* Block traversal through all symlinks
259 (implies OEXT_NO_MAGICLINKS) */
262 #ifndef RESOLVE_BENEATH
263 #define RESOLVE_BENEATH 0x08 /* Block "lexical" trickery like
264 "..", symlinks, and absolute
265 paths which escape the dirfd. */
268 #ifndef RESOLVE_IN_ROOT
269 #define RESOLVE_IN_ROOT 0x10 /* Make all jumps to "/" and ".."
270 be scoped inside the dirfd
271 (similar to chroot(2)). */
274 #define PROTECT_LOOKUP_BENEATH (RESOLVE_BENEATH | RESOLVE_NO_XDEV | RESOLVE_NO_MAGICLINKS | RESOLVE_NO_SYMLINKS)
275 #define PROTECT_LOOKUP_BENEATH_WITH_SYMLINKS (PROTECT_LOOKUP_BENEATH & ~RESOLVE_NO_SYMLINKS)
276 #define PROTECT_LOOKUP_BENEATH_WITH_MAGICLINKS (PROTECT_LOOKUP_BENEATH & ~(RESOLVE_NO_SYMLINKS | RESOLVE_NO_MAGICLINKS))
277 #define PROTECT_LOOKUP_BENEATH_XDEV (PROTECT_LOOKUP_BENEATH & ~RESOLVE_NO_XDEV)
279 #define PROTECT_LOOKUP_ABSOLUTE (PROTECT_LOOKUP_BENEATH & ~RESOLVE_BENEATH)
280 #define PROTECT_LOOKUP_ABSOLUTE_WITH_SYMLINKS (PROTECT_LOOKUP_ABSOLUTE & ~RESOLVE_NO_SYMLINKS)
281 #define PROTECT_LOOKUP_ABSOLUTE_WITH_MAGICLINKS (PROTECT_LOOKUP_ABSOLUTE & ~(RESOLVE_NO_SYMLINKS | RESOLVE_NO_MAGICLINKS))
282 #define PROTECT_LOOKUP_ABSOLUTE_XDEV (PROTECT_LOOKUP_ABSOLUTE & ~RESOLVE_NO_XDEV)
283 #define PROTECT_LOOKUP_ABSOLUTE_XDEV_SYMLINKS (PROTECT_LOOKUP_ABSOLUTE_WITH_SYMLINKS & ~RESOLVE_NO_XDEV)
285 #define PROTECT_OPATH_FILE (O_NOFOLLOW | O_PATH | O_CLOEXEC)
286 #define PROTECT_OPATH_DIRECTORY (PROTECT_OPATH_FILE | O_DIRECTORY)
288 #define PROTECT_OPEN_WITH_TRAILING_SYMLINKS (O_CLOEXEC | O_NOCTTY | O_RDONLY)
289 #define PROTECT_OPEN (PROTECT_OPEN_WITH_TRAILING_SYMLINKS | O_NOFOLLOW)
291 #define PROTECT_OPEN_W_WITH_TRAILING_SYMLINKS (O_CLOEXEC | O_NOCTTY | O_WRONLY)
292 #define PROTECT_OPEN_W (PROTECT_OPEN_W_WITH_TRAILING_SYMLINKS | O_NOFOLLOW)
293 #define PROTECT_OPEN_RW (O_CLOEXEC | O_NOCTTY | O_RDWR | O_NOFOLLOW)
296 static inline int openat2(int dfd
, const char *filename
, struct lxc_open_how
*how
, size_t size
)
298 return syscall(__NR_openat2
, dfd
, filename
, how
, size
);
300 #endif /* HAVE_OPENAT2 */
302 #ifndef CLOSE_RANGE_UNSHARE
303 #define CLOSE_RANGE_UNSHARE (1U << 1)
306 #ifndef CLOSE_RANGE_CLOEXEC
307 #define CLOSE_RANGE_CLOEXEC (1U << 2)
310 #if !HAVE_CLOSE_RANGE
311 static inline int close_range(unsigned int fd
, unsigned int max_fd
, unsigned int flags
)
313 return syscall(__NR_close_range
, fd
, max_fd
, flags
);
317 #if !HAVE_SYS_PERSONALITY_H
318 static inline int personality(unsigned long persona
)
320 return syscall(__NR_personality
, persona
);
324 /* arg1 of prctl() */
325 #ifndef PR_SCHED_CORE
326 #define PR_SCHED_CORE 62
329 /* arg2 of prctl() */
330 #ifndef PR_SCHED_CORE_GET
331 #define PR_SCHED_CORE_GET 0
334 #ifndef PR_SCHED_CORE_CREATE
335 #define PR_SCHED_CORE_CREATE 1 /* create unique core_sched cookie */
338 #ifndef PR_SCHED_CORE_SHARE_TO
339 #define PR_SCHED_CORE_SHARE_TO 2 /* push core_sched cookie to pid */
342 #ifndef PR_SCHED_CORE_SHARE_FROM
343 #define PR_SCHED_CORE_SHARE_FROM 3 /* pull core_sched cookie to pid */
346 #ifndef PR_SCHED_CORE_MAX
347 #define PR_SCHED_CORE_MAX 4
350 /* arg3 of prctl() */
351 #ifndef PR_SCHED_CORE_SCOPE_THREAD
352 #define PR_SCHED_CORE_SCOPE_THREAD 0
355 #ifndef PR_SCHED_CORE_SCOPE_THREAD_GROUP
356 #define PR_SCHED_CORE_SCOPE_THREAD_GROUP 1
359 #ifndef PR_SCHED_CORE_SCOPE_PROCESS_GROUP
360 #define PR_SCHED_CORE_SCOPE_PROCESS_GROUP 2
363 #define INVALID_SCHED_CORE_COOKIE ((__u64)-1)
365 static inline bool core_scheduling_cookie_valid(__u64 cookie
)
367 return (cookie
> 0) && (cookie
!= INVALID_SCHED_CORE_COOKIE
);
370 static inline int core_scheduling_cookie_get(pid_t pid
, __u64
*cookie
)
375 return ret_errno(EINVAL
);
377 ret
= prctl(PR_SCHED_CORE
, PR_SCHED_CORE_GET
, pid
,
378 PR_SCHED_CORE_SCOPE_THREAD
, (unsigned long)cookie
);
380 *cookie
= INVALID_SCHED_CORE_COOKIE
;
387 static inline int core_scheduling_cookie_create_threadgroup(pid_t pid
)
391 ret
= prctl(PR_SCHED_CORE
, PR_SCHED_CORE_CREATE
, pid
,
392 PR_SCHED_CORE_SCOPE_THREAD_GROUP
, 0);
399 static inline int core_scheduling_cookie_share_with(pid_t pid
)
401 return prctl(PR_SCHED_CORE
, PR_SCHED_CORE_SHARE_FROM
, pid
,
402 PR_SCHED_CORE_SCOPE_THREAD
, 0);
405 #endif /* __LXC_SYSCALL_WRAPPER_H */