This source file includes following definitions.
- ATTRIBUTE_FORMAT_PRINTF
- release_context
- set_attribute
- export_filter
- main
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36 #include "config.h"
37
38 #include <assert.h>
39 #include <errno.h>
40 #include <limits.h>
41 #include <stdarg.h>
42 #include <stdlib.h>
43 #include <stdint.h>
44 #include <stdio.h>
45 #include <time.h>
46
47 #include <asm/prctl.h>
48 #include <sys/ioctl.h>
49 #include <sys/mman.h>
50 #include <sys/prctl.h>
51 #include <sys/types.h>
52 #include <sys/stat.h>
53 #include <linux/futex.h>
54 #include <linux/filter.h>
55 #include <linux/seccomp.h>
56 #include <fcntl.h>
57 #include <sched.h>
58 #include <seccomp.h>
59 #include <unistd.h>
60
61 #include <attribute.h>
62
63 #ifndef ARCH_CET_STATUS
64 #define ARCH_CET_STATUS 0x3001
65 #endif
66
67 static ATTRIBUTE_FORMAT_PRINTF (2, 3) _Noreturn void
68 fail (int error, const char *format, ...)
69 {
70 va_list ap;
71 va_start (ap, format);
72 vfprintf (stderr, format, ap);
73 va_end (ap);
74 if (error == 0)
75 fputc ('\n', stderr);
76 else
77 {
78 fputs (": ", stderr);
79 errno = error;
80 perror (NULL);
81 }
82 fflush (NULL);
83 exit (EXIT_FAILURE);
84 }
85
86
87
88
89 static scmp_filter_ctx ctx;
90
91 static void
92 release_context (void)
93 {
94 seccomp_release (ctx);
95 }
96
97
98
99
100 static void
101 set_attribute (enum scmp_filter_attr attr, uint32_t value)
102 {
103 int status = seccomp_attr_set (ctx, attr, value);
104 if (status < 0)
105 fail (-status, "seccomp_attr_set (ctx, %u, %u)", attr, value);
106 }
107
108
109
110
111
112 #define RULE(action, syscall, ...) \
113 do \
114 { \
115 const struct scmp_arg_cmp arg_array[] = {__VA_ARGS__}; \
116 enum { arg_cnt = sizeof arg_array / sizeof *arg_array }; \
117 int status = seccomp_rule_add_array (ctx, (action), (syscall), \
118 arg_cnt, arg_array); \
119 if (status < 0) \
120 fail (-status, "seccomp_rule_add_array (%s, %s, %d, {%s})", \
121 #action, #syscall, arg_cnt, #__VA_ARGS__); \
122 } \
123 while (false)
124
125 static void
126 export_filter (const char *file,
127 int (*function) (const scmp_filter_ctx, int),
128 const char *name)
129 {
130 int fd;
131 do
132 fd = open (file,
133 O_WRONLY | O_CREAT | O_TRUNC | O_BINARY | O_CLOEXEC,
134 0644);
135 while (fd < 0 && errno == EINTR);
136 if (fd < 0)
137 fail (errno, "open %s", file);
138 int status = function (ctx, fd);
139 if (status < 0)
140 fail (-status, "%s", name);
141 if (close (fd) != 0)
142 fail (errno, "close");
143 }
144
145 #define EXPORT_FILTER(file, function) \
146 export_filter ((file), (function), #function)
147
148 int
149 main (int argc, char **argv)
150 {
151 if (argc != 5)
152 fail (0, "usage: %s out.bpf out.pfc out-exec.bpf out-exec.pfc",
153 argv[0]);
154
155
156 ctx = seccomp_init (SCMP_ACT_KILL_PROCESS);
157 if (ctx == NULL)
158 fail (0, "seccomp_init");
159 atexit (release_context);
160
161
162 set_attribute (SCMP_FLTATR_ACT_BADARCH, SCMP_ACT_KILL_PROCESS);
163 set_attribute (SCMP_FLTATR_CTL_NNP, 1);
164 set_attribute (SCMP_FLTATR_CTL_TSYNC, 1);
165
166 static_assert (CHAR_BIT == 8);
167 static_assert (sizeof (int) == 4 && INT_MIN == INT32_MIN
168 && INT_MAX == INT32_MAX);
169 static_assert (sizeof (long) == 8 && LONG_MIN == INT64_MIN
170 && LONG_MAX == INT64_MAX);
171 static_assert (sizeof (void *) == 8);
172 assert ((uintptr_t) NULL == 0);
173
174
175 RULE (SCMP_ACT_ALLOW, SCMP_SYS (exit));
176 RULE (SCMP_ACT_ALLOW, SCMP_SYS (exit_group));
177
178
179
180
181 static_assert (MAP_PRIVATE != 0);
182 static_assert (MAP_SHARED != 0);
183 RULE (SCMP_ACT_ALLOW, SCMP_SYS (mmap),
184 SCMP_A2_32 (SCMP_CMP_MASKED_EQ,
185 ~(PROT_NONE | PROT_READ | PROT_WRITE)),
186
187
188
189 SCMP_A3_32 (SCMP_CMP_MASKED_EQ,
190 ~(MAP_SHARED | MAP_PRIVATE | MAP_FILE
191 | MAP_ANONYMOUS | MAP_FIXED | MAP_DENYWRITE
192 | MAP_STACK | MAP_NORESERVE),
193 0));
194 RULE (SCMP_ACT_ALLOW, SCMP_SYS (mmap),
195 SCMP_A2_32 (SCMP_CMP_MASKED_EQ,
196 ~(PROT_NONE | PROT_READ | PROT_EXEC)),
197
198
199 SCMP_A3_32 (SCMP_CMP_MASKED_EQ,
200 ~(MAP_PRIVATE | MAP_ANONYMOUS | MAP_FIXED
201 | MAP_DENYWRITE),
202 0));
203 RULE (SCMP_ACT_ALLOW, SCMP_SYS (munmap));
204 RULE (SCMP_ACT_ALLOW, SCMP_SYS (mprotect),
205
206 SCMP_A2_32 (SCMP_CMP_MASKED_EQ,
207 ~(PROT_NONE | PROT_READ | PROT_WRITE), 0));
208
209
210 RULE (SCMP_ACT_ALLOW, SCMP_SYS (rseq));
211
212
213 RULE (SCMP_ACT_ALLOW, SCMP_SYS (futex),
214 SCMP_A1_32 (SCMP_CMP_EQ, FUTEX_WAKE_PRIVATE));
215
216
217 RULE (SCMP_ACT_ALLOW, SCMP_SYS (brk));
218
219
220 RULE (SCMP_ACT_ALLOW, SCMP_SYS (uname));
221 RULE (SCMP_ACT_ALLOW, SCMP_SYS (getuid));
222 RULE (SCMP_ACT_ALLOW, SCMP_SYS (geteuid));
223 RULE (SCMP_ACT_ALLOW, SCMP_SYS (getpid));
224 RULE (SCMP_ACT_ALLOW, SCMP_SYS (gettid));
225 RULE (SCMP_ACT_ALLOW, SCMP_SYS (getpgrp));
226
227
228
229
230 RULE (SCMP_ACT_ALLOW, SCMP_SYS (read));
231 RULE (SCMP_ACT_ALLOW, SCMP_SYS (pread64));
232 RULE (SCMP_ACT_ALLOW, SCMP_SYS (write));
233 RULE (SCMP_ACT_ALLOW, SCMP_SYS (close));
234 RULE (SCMP_ACT_ALLOW, SCMP_SYS (lseek));
235 RULE (SCMP_ACT_ALLOW, SCMP_SYS (dup));
236 RULE (SCMP_ACT_ALLOW, SCMP_SYS (dup2));
237 RULE (SCMP_ACT_ALLOW, SCMP_SYS (fstat));
238
239
240
241 RULE (SCMP_ACT_ALLOW, SCMP_SYS (access));
242 RULE (SCMP_ACT_ALLOW, SCMP_SYS (faccessat));
243 #ifdef __NR_faccessat2
244 RULE (SCMP_ACT_ALLOW, SCMP_SYS (faccessat2));
245 #endif
246 RULE (SCMP_ACT_ALLOW, SCMP_SYS (stat));
247 RULE (SCMP_ACT_ALLOW, SCMP_SYS (stat64));
248 RULE (SCMP_ACT_ALLOW, SCMP_SYS (lstat));
249 RULE (SCMP_ACT_ALLOW, SCMP_SYS (lstat64));
250 RULE (SCMP_ACT_ALLOW, SCMP_SYS (fstatat64));
251 RULE (SCMP_ACT_ALLOW, SCMP_SYS (newfstatat));
252 RULE (SCMP_ACT_ALLOW, SCMP_SYS (readlink));
253 RULE (SCMP_ACT_ALLOW, SCMP_SYS (readlinkat));
254 RULE (SCMP_ACT_ALLOW, SCMP_SYS (getcwd));
255
256
257
258 static_assert (O_WRONLY != 0);
259 static_assert (O_RDWR != 0);
260 static_assert (O_CREAT != 0);
261 RULE (SCMP_ACT_ALLOW, SCMP_SYS (open),
262 SCMP_A1_32 (SCMP_CMP_MASKED_EQ,
263 ~(O_RDONLY | O_BINARY | O_CLOEXEC | O_PATH
264 | O_DIRECTORY | O_NOFOLLOW),
265 0));
266 RULE (SCMP_ACT_ALLOW, SCMP_SYS (openat),
267 SCMP_A2_32 (SCMP_CMP_MASKED_EQ,
268 ~(O_RDONLY | O_BINARY | O_CLOEXEC | O_PATH
269 | O_DIRECTORY | O_NOFOLLOW),
270 0));
271
272
273 RULE (SCMP_ACT_ALLOW, SCMP_SYS (ioctl),
274 SCMP_A0_32 (SCMP_CMP_EQ, STDIN_FILENO),
275 SCMP_A1_32 (SCMP_CMP_EQ, TIOCGPGRP));
276
277
278 RULE (SCMP_ACT_ALLOW, SCMP_SYS (fcntl),
279 SCMP_A1_32 (SCMP_CMP_EQ, F_GETFL));
280 RULE (SCMP_ACT_ALLOW, SCMP_SYS (fcntl64),
281 SCMP_A1_32 (SCMP_CMP_EQ, F_GETFL));
282
283
284 RULE (SCMP_ACT_ALLOW, SCMP_SYS (getrandom));
285
286
287 RULE (SCMP_ACT_ALLOW, SCMP_SYS (umask));
288
289
290 RULE (SCMP_ACT_ALLOW, SCMP_SYS (pipe));
291 RULE (SCMP_ACT_ALLOW, SCMP_SYS (pipe2));
292
293
294 RULE (SCMP_ACT_ALLOW, SCMP_SYS (getrlimit));
295 RULE (SCMP_ACT_ALLOW, SCMP_SYS (prlimit64),
296 SCMP_A0_32 (SCMP_CMP_EQ, 0) ,
297 SCMP_A2_64 (SCMP_CMP_EQ, 0) );
298
299
300 RULE (SCMP_ACT_ERRNO (EPERM), SCMP_SYS (prlimit64),
301 SCMP_A0_32 (SCMP_CMP_EQ, 0) ,
302 SCMP_A2_64 (SCMP_CMP_NE, 0) );
303
304
305 RULE (SCMP_ACT_ALLOW, SCMP_SYS (sigaction));
306 RULE (SCMP_ACT_ALLOW, SCMP_SYS (rt_sigaction));
307 RULE (SCMP_ACT_ALLOW, SCMP_SYS (sigprocmask));
308 RULE (SCMP_ACT_ALLOW, SCMP_SYS (rt_sigprocmask));
309
310
311 RULE (SCMP_ACT_ALLOW, SCMP_SYS (clock_gettime),
312 SCMP_A0_32 (SCMP_CMP_EQ, CLOCK_REALTIME));
313 RULE (SCMP_ACT_ALLOW, SCMP_SYS (time));
314 RULE (SCMP_ACT_ALLOW, SCMP_SYS (gettimeofday));
315
316
317 RULE (SCMP_ACT_ALLOW, SCMP_SYS (timer_create));
318 RULE (SCMP_ACT_ALLOW, SCMP_SYS (timerfd_create));
319
320
321
322 RULE (SCMP_ACT_ALLOW, SCMP_SYS (clone),
323 SCMP_A0_64 (SCMP_CMP_MASKED_EQ,
324
325
326 ~(CLONE_VM | CLONE_FS | CLONE_FILES
327 | CLONE_SYSVSEM | CLONE_SIGHAND | CLONE_THREAD
328 | CLONE_SETTLS | CLONE_PARENT_SETTID
329 | CLONE_CHILD_CLEARTID),
330 0));
331
332 RULE (SCMP_ACT_ALLOW, SCMP_SYS (clone3));
333 RULE (SCMP_ACT_ALLOW, SCMP_SYS (sigaltstack));
334 RULE (SCMP_ACT_ALLOW, SCMP_SYS (set_robust_list));
335
336
337 RULE (SCMP_ACT_ALLOW, SCMP_SYS (prctl),
338 SCMP_A0_32 (SCMP_CMP_EQ, PR_SET_NAME));
339
340
341 RULE (SCMP_ACT_ALLOW, SCMP_SYS (eventfd));
342 RULE (SCMP_ACT_ALLOW, SCMP_SYS (eventfd2));
343 RULE (SCMP_ACT_ALLOW, SCMP_SYS (wait4));
344 RULE (SCMP_ACT_ALLOW, SCMP_SYS (poll));
345 RULE (SCMP_ACT_ALLOW, SCMP_SYS (pidfd_open),
346 SCMP_A1_32 (SCMP_CMP_EQ, 0));
347
348
349
350 RULE (SCMP_ACT_ERRNO (EACCES), SCMP_SYS (socket));
351
352 EXPORT_FILTER (argv[1], seccomp_export_bpf);
353 EXPORT_FILTER (argv[2], seccomp_export_pfc);
354
355
356
357
358
359
360 RULE (SCMP_ACT_ALLOW, SCMP_SYS (execve));
361 RULE (SCMP_ACT_ALLOW, SCMP_SYS (set_tid_address));
362 RULE (SCMP_ACT_ERRNO (EINVAL), SCMP_SYS (prctl),
363 SCMP_A0_32 (SCMP_CMP_EQ, PR_CAPBSET_READ));
364 RULE (SCMP_ACT_ALLOW, SCMP_SYS (arch_prctl),
365 SCMP_A0_32 (SCMP_CMP_EQ, ARCH_SET_FS));
366 RULE (SCMP_ACT_ERRNO (EINVAL), SCMP_SYS (arch_prctl),
367 SCMP_A0_32 (SCMP_CMP_EQ, ARCH_CET_STATUS));
368 RULE (SCMP_ACT_ALLOW, SCMP_SYS (statfs));
369
370
371
372
373 RULE (SCMP_ACT_ALLOW, SCMP_SYS (prctl),
374 SCMP_A0_32 (SCMP_CMP_EQ, PR_SET_NO_NEW_PRIVS),
375 SCMP_A1_64 (SCMP_CMP_EQ, 1), SCMP_A2_64 (SCMP_CMP_EQ, 0),
376 SCMP_A3_64 (SCMP_CMP_EQ, 0), SCMP_A4_64 (SCMP_CMP_EQ, 0));
377 RULE (SCMP_ACT_ALLOW, SCMP_SYS (seccomp),
378 SCMP_A0_32 (SCMP_CMP_EQ, SECCOMP_SET_MODE_FILTER),
379 SCMP_A1_32 (SCMP_CMP_EQ, SECCOMP_FILTER_FLAG_TSYNC));
380
381 EXPORT_FILTER (argv[3], seccomp_export_bpf);
382 EXPORT_FILTER (argv[4], seccomp_export_pfc);
383 }