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