]> git.proxmox.com Git - mirror_lxc.git/blob - src/lxc/syscall_wrappers.h
f50875cc12fb9d03e43b9d8ab144402f45072153
[mirror_lxc.git] / src / lxc / syscall_wrappers.h
1 /* SPDX-License-Identifier: LGPL-2.1+ */
2
3 #ifndef __LXC_SYSCALL_WRAPPER_H
4 #define __LXC_SYSCALL_WRAPPER_H
5
6 #ifndef _GNU_SOURCE
7 #define _GNU_SOURCE 1
8 #endif
9 #include <asm/unistd.h>
10 #include <errno.h>
11 #include <linux/keyctl.h>
12 #include <sched.h>
13 #include <stdint.h>
14 #include <sys/syscall.h>
15 #include <sys/types.h>
16 #include <unistd.h>
17
18 #include "config.h"
19 #include "macro.h"
20 #include "syscall_numbers.h"
21
22 #ifdef HAVE_LINUX_MEMFD_H
23 #include <linux/memfd.h>
24 #endif
25
26 #ifdef HAVE_SYS_SIGNALFD_H
27 #include <sys/signalfd.h>
28 #endif
29
30 #ifdef HAVE_STRUCT_OPEN_HOW
31 #include <linux/openat2.h>
32 #endif
33
34 #if HAVE_SYS_PERSONALITY_H
35 #include <sys/personality.h>
36 #endif
37
38 typedef int32_t key_serial_t;
39
40 #if !HAVE_KEYCTL
41 static inline long __keyctl(int cmd, unsigned long arg2, unsigned long arg3,
42 unsigned long arg4, unsigned long arg5)
43 {
44 return syscall(__NR_keyctl, cmd, arg2, arg3, arg4, arg5);
45 }
46 #define keyctl __keyctl
47 #endif
48
49 #ifndef F_LINUX_SPECIFIC_BASE
50 #define F_LINUX_SPECIFIC_BASE 1024
51 #endif
52 #ifndef F_ADD_SEALS
53 #define F_ADD_SEALS (F_LINUX_SPECIFIC_BASE + 9)
54 #define F_GET_SEALS (F_LINUX_SPECIFIC_BASE + 10)
55 #endif
56 #ifndef F_SEAL_SEAL
57 #define F_SEAL_SEAL 0x0001
58 #define F_SEAL_SHRINK 0x0002
59 #define F_SEAL_GROW 0x0004
60 #define F_SEAL_WRITE 0x0008
61 #endif
62
63 #ifndef HAVE_MEMFD_CREATE
64 static inline int memfd_create_lxc(const char *name, unsigned int flags)
65 {
66 return syscall(__NR_memfd_create, name, flags);
67 }
68 #define memfd_create memfd_create_lxc
69 #else
70 extern int memfd_create(const char *name, unsigned int flags);
71 #endif
72
73 #ifndef HAVE_PIVOT_ROOT
74 static int pivot_root(const char *new_root, const char *put_old)
75 {
76 return syscall(__NR_pivot_root, new_root, put_old);
77 }
78 #else
79 extern int pivot_root(const char *new_root, const char *put_old);
80 #endif
81
82 /* Define sethostname() if missing from the C library */
83 #ifndef HAVE_SETHOSTNAME
84 static inline int sethostname(const char *name, size_t len)
85 {
86 return syscall(__NR_sethostname, name, len);
87 }
88 #endif
89
90 /* Define setns() if missing from the C library */
91 #ifndef HAVE_SETNS
92 static inline int setns(int fd, int nstype)
93 {
94 return syscall(__NR_setns, fd, nstype);
95 }
96 #endif
97
98 #ifndef HAVE_SYS_SIGNALFD_H
99 struct signalfd_siginfo {
100 uint32_t ssi_signo;
101 int32_t ssi_errno;
102 int32_t ssi_code;
103 uint32_t ssi_pid;
104 uint32_t ssi_uid;
105 int32_t ssi_fd;
106 uint32_t ssi_tid;
107 uint32_t ssi_band;
108 uint32_t ssi_overrun;
109 uint32_t ssi_trapno;
110 int32_t ssi_status;
111 int32_t ssi_int;
112 uint64_t ssi_ptr;
113 uint64_t ssi_utime;
114 uint64_t ssi_stime;
115 uint64_t ssi_addr;
116 uint8_t __pad[48];
117 };
118
119 static inline int signalfd(int fd, const sigset_t *mask, int flags)
120 {
121 int retval;
122
123 retval = syscall(__NR_signalfd4, fd, mask, _NSIG / 8, flags);
124 #ifdef __NR_signalfd
125 if (errno == ENOSYS && flags == 0)
126 retval = syscall(__NR_signalfd, fd, mask, _NSIG / 8);
127 #endif
128
129 return retval;
130 }
131 #endif
132
133 /* Define unshare() if missing from the C library */
134 #ifndef HAVE_UNSHARE
135 static inline int unshare(int flags)
136 {
137 return syscall(__NR_unshare, flags);
138 }
139 #else
140 extern int unshare(int);
141 #endif
142
143 /* Define faccessat() if missing from the C library */
144 #ifndef HAVE_FACCESSAT
145 static int faccessat(int __fd, const char *__file, int __type, int __flag)
146 {
147 return syscall(__NR_faccessat, __fd, __file, __type, __flag);
148 }
149 #endif
150
151 #ifndef HAVE_MOVE_MOUNT
152 static inline int move_mount_lxc(int from_dfd, const char *from_pathname,
153 int to_dfd, const char *to_pathname,
154 unsigned int flags)
155 {
156 return syscall(__NR_move_mount, from_dfd, from_pathname, to_dfd,
157 to_pathname, flags);
158 }
159 #define move_mount move_mount_lxc
160 #else
161 extern int move_mount(int from_dfd, const char *from_pathname, int to_dfd,
162 const char *to_pathname, unsigned int flags);
163 #endif
164
165 #ifndef HAVE_OPEN_TREE
166 static inline int open_tree_lxc(int dfd, const char *filename, unsigned int flags)
167 {
168 return syscall(__NR_open_tree, dfd, filename, flags);
169 }
170 #define open_tree open_tree_lxc
171 #else
172 extern int open_tree(int dfd, const char *filename, unsigned int flags);
173 #endif
174
175 #ifndef HAVE_FSOPEN
176 static inline int fsopen_lxc(const char *fs_name, unsigned int flags)
177 {
178 return syscall(__NR_fsopen, fs_name, flags);
179 }
180 #define fsopen fsopen_lxc
181 #else
182 extern int fsopen(const char *fs_name, unsigned int flags);
183 #endif
184
185 #ifndef HAVE_FSPICK
186 static inline int fspick_lxc(int dfd, const char *path, unsigned int flags)
187 {
188 return syscall(__NR_fspick, dfd, path, flags);
189 }
190 #define fspick fspick_lxc
191 #else
192 extern int fspick(int dfd, const char *path, unsigned int flags);
193 #endif
194
195 #ifndef HAVE_FSCONFIG
196 static inline int fsconfig_lxc(int fd, unsigned int cmd, const char *key, const void *value, int aux)
197 {
198 return syscall(__NR_fsconfig, fd, cmd, key, value, aux);
199 }
200 #define fsconfig fsconfig_lxc
201 #else
202 extern int fsconfig(int fd, unsigned int cmd, const char *key, const void *value, int aux);
203 #endif
204
205 #ifndef HAVE_FSMOUNT
206 static inline int fsmount_lxc(int fs_fd, unsigned int flags, unsigned int attr_flags)
207 {
208 return syscall(__NR_fsmount, fs_fd, flags, attr_flags);
209 }
210 #define fsmount fsmount_lxc
211 #else
212 extern int fsmount(int fs_fd, unsigned int flags, unsigned int attr_flags);
213 #endif
214
215 /*
216 * mount_setattr()
217 */
218 struct lxc_mount_attr {
219 __u64 attr_set;
220 __u64 attr_clr;
221 __u64 propagation;
222 __u64 userns_fd;
223 };
224
225 #ifndef HAVE_MOUNT_SETATTR
226 static inline int mount_setattr(int dfd, const char *path, unsigned int flags,
227 struct lxc_mount_attr *attr, size_t size)
228 {
229 return syscall(__NR_mount_setattr, dfd, path, flags, attr, size);
230 }
231 #endif
232
233 /*
234 * Arguments for how openat2(2) should open the target path. If only @flags and
235 * @mode are non-zero, then openat2(2) operates very similarly to openat(2).
236 *
237 * However, unlike openat(2), unknown or invalid bits in @flags result in
238 * -EINVAL rather than being silently ignored. @mode must be zero unless one of
239 * {O_CREAT, O_TMPFILE} are set.
240 *
241 * @flags: O_* flags.
242 * @mode: O_CREAT/O_TMPFILE file mode.
243 * @resolve: RESOLVE_* flags.
244 */
245 struct lxc_open_how {
246 __u64 flags;
247 __u64 mode;
248 __u64 resolve;
249 };
250
251 /* how->resolve flags for openat2(2). */
252 #ifndef RESOLVE_NO_XDEV
253 #define RESOLVE_NO_XDEV 0x01 /* Block mount-point crossings
254 (includes bind-mounts). */
255 #endif
256
257 #ifndef RESOLVE_NO_MAGICLINKS
258 #define RESOLVE_NO_MAGICLINKS 0x02 /* Block traversal through procfs-style
259 "magic-links". */
260 #endif
261
262 #ifndef RESOLVE_NO_SYMLINKS
263 #define RESOLVE_NO_SYMLINKS 0x04 /* Block traversal through all symlinks
264 (implies OEXT_NO_MAGICLINKS) */
265 #endif
266
267 #ifndef RESOLVE_BENEATH
268 #define RESOLVE_BENEATH 0x08 /* Block "lexical" trickery like
269 "..", symlinks, and absolute
270 paths which escape the dirfd. */
271 #endif
272
273 #ifndef RESOLVE_IN_ROOT
274 #define RESOLVE_IN_ROOT 0x10 /* Make all jumps to "/" and ".."
275 be scoped inside the dirfd
276 (similar to chroot(2)). */
277 #endif
278
279 #define PROTECT_LOOKUP_BENEATH (RESOLVE_BENEATH | RESOLVE_NO_XDEV | RESOLVE_NO_MAGICLINKS | RESOLVE_NO_SYMLINKS)
280 #define PROTECT_LOOKUP_BENEATH_WITH_SYMLINKS (PROTECT_LOOKUP_BENEATH & ~RESOLVE_NO_SYMLINKS)
281 #define PROTECT_LOOKUP_BENEATH_WITH_MAGICLINKS (PROTECT_LOOKUP_BENEATH & ~(RESOLVE_NO_SYMLINKS | RESOLVE_NO_MAGICLINKS))
282 #define PROTECT_LOOKUP_BENEATH_XDEV (PROTECT_LOOKUP_BENEATH & ~RESOLVE_NO_XDEV)
283
284 #define PROTECT_LOOKUP_ABSOLUTE (PROTECT_LOOKUP_BENEATH & ~RESOLVE_BENEATH)
285 #define PROTECT_LOOKUP_ABSOLUTE_WITH_SYMLINKS (PROTECT_LOOKUP_ABSOLUTE & ~RESOLVE_NO_SYMLINKS)
286 #define PROTECT_LOOKUP_ABSOLUTE_WITH_MAGICLINKS (PROTECT_LOOKUP_ABSOLUTE & ~(RESOLVE_NO_SYMLINKS | RESOLVE_NO_MAGICLINKS))
287 #define PROTECT_LOOKUP_ABSOLUTE_XDEV (PROTECT_LOOKUP_ABSOLUTE & ~RESOLVE_NO_XDEV)
288
289 #define PROTECT_OPATH_FILE (O_NOFOLLOW | O_PATH | O_CLOEXEC)
290 #define PROTECT_OPATH_DIRECTORY (PROTECT_OPATH_FILE | O_DIRECTORY)
291
292 #define PROTECT_OPEN_WITH_TRAILING_SYMLINKS (O_CLOEXEC | O_NOCTTY | O_RDONLY)
293 #define PROTECT_OPEN (PROTECT_OPEN_WITH_TRAILING_SYMLINKS | O_NOFOLLOW)
294
295 #define PROTECT_OPEN_W_WITH_TRAILING_SYMLINKS (O_CLOEXEC | O_NOCTTY | O_WRONLY)
296 #define PROTECT_OPEN_W (PROTECT_OPEN_W_WITH_TRAILING_SYMLINKS | O_NOFOLLOW)
297 #define PROTECT_OPEN_RW (O_CLOEXEC | O_NOCTTY | O_RDWR | O_NOFOLLOW)
298
299 #ifndef HAVE_OPENAT2
300 static inline int openat2(int dfd, const char *filename, struct lxc_open_how *how, size_t size)
301 {
302 /* When struct open_how is updated we should update lxc as well. */
303 #ifdef HAVE_STRUCT_OPEN_HOW
304 BUILD_BUG_ON(sizeof(struct lxc_open_how) != sizeof(struct open_how));
305 #endif
306 return syscall(__NR_openat2, dfd, filename, (struct open_how *)how, size);
307 }
308 #endif /* HAVE_OPENAT2 */
309
310 #ifndef CLOSE_RANGE_UNSHARE
311 #define CLOSE_RANGE_UNSHARE (1U << 1)
312 #endif
313
314 #ifndef CLOSE_RANGE_CLOEXEC
315 #define CLOSE_RANGE_CLOEXEC (1U << 2)
316 #endif
317
318 #ifndef HAVE_CLOSE_RANGE
319 static inline int close_range(unsigned int fd, unsigned int max_fd, unsigned int flags)
320 {
321 return syscall(__NR_close_range, fd, max_fd, flags);
322 }
323 #endif
324
325 #ifndef HAVE_SYS_PERSONALITY_H
326 static inline int personality(unsigned long persona)
327 {
328 return syscall(__NR_personality, persona);
329 }
330 #endif
331
332 #endif /* __LXC_SYSCALL_WRAPPER_H */