aboutsummaryrefslogtreecommitdiffstats
path: root/src/fseccomp
diff options
context:
space:
mode:
authorLibravatar Topi Miettinen <toiwoton@gmail.com>2020-03-14 00:07:06 +0200
committerLibravatar Topi Miettinen <topimiettinen@users.noreply.github.com>2020-03-28 11:24:25 +0000
commit88eadbf31fe25dcd7c224a5d92f71c79ccf6c9d3 (patch)
tree6b4d2a805a2900755bfc857586a10948b3c8395e /src/fseccomp
parentAdded compatibility with BetterDiscord (#3300) (diff)
downloadfirejail-88eadbf31fe25dcd7c224a5d92f71c79ccf6c9d3.tar.gz
firejail-88eadbf31fe25dcd7c224a5d92f71c79ccf6c9d3.tar.zst
firejail-88eadbf31fe25dcd7c224a5d92f71c79ccf6c9d3.zip
seccomp: allow defining separate filters for 32-bit arch
System calls (names and numbers) are not exactly the same for 32 bit and 64 bit architectures. Let's allow defining separate filters for 32-bit arch using seccomp.32, seccomp.32.drop, seccomp.32.keep. This is useful for mixed 64/32 bit application environments like Steam and Wine. Implement protocol and mdwx filtering also for 32 bit arch. It's still better to block secondary archs completely if not needed. Lists of supported system calls are also updated. Warn if preload libraries would be needed due to trace, tracelog or postexecseccomp (seccomp.drop=execve etc), because a 32-bit dynamic linker does not understand the 64 bit preload libraries. Closes #3267. Signed-off-by: Topi Miettinen <toiwoton@gmail.com>
Diffstat (limited to 'src/fseccomp')
-rw-r--r--src/fseccomp/Makefile.in4
-rw-r--r--src/fseccomp/errno.c204
-rw-r--r--src/fseccomp/fseccomp.h34
-rw-r--r--src/fseccomp/main.c41
-rw-r--r--src/fseccomp/protocol.c21
-rw-r--r--src/fseccomp/seccomp.c143
-rw-r--r--src/fseccomp/seccomp_file.c33
-rw-r--r--src/fseccomp/syscall.c1632
8 files changed, 203 insertions, 1909 deletions
diff --git a/src/fseccomp/Makefile.in b/src/fseccomp/Makefile.in
index 67e074b3d..8623db6f8 100644
--- a/src/fseccomp/Makefile.in
+++ b/src/fseccomp/Makefile.in
@@ -5,8 +5,8 @@ include ../common.mk
5%.o : %.c $(H_FILE_LIST) ../include/common.h ../include/syscall.h 5%.o : %.c $(H_FILE_LIST) ../include/common.h ../include/syscall.h
6 $(CC) $(CFLAGS) $(EXTRA_CFLAGS) $(INCLUDE) -c $< -o $@ 6 $(CC) $(CFLAGS) $(EXTRA_CFLAGS) $(INCLUDE) -c $< -o $@
7 7
8fseccomp: $(OBJS) 8fseccomp: $(OBJS) ../lib/errno.o ../lib/syscall.o
9 $(CC) $(LDFLAGS) -o $@ $(OBJS) $(LIBS) $(EXTRA_LDFLAGS) 9 $(CC) $(LDFLAGS) -o $@ $(OBJS) ../lib/errno.o ../lib/syscall.o $(LIBS) $(EXTRA_LDFLAGS)
10 10
11clean:; rm -fr *.o fseccomp *.gcov *.gcda *.gcno *.plist 11clean:; rm -fr *.o fseccomp *.gcov *.gcda *.gcno *.plist
12 12
diff --git a/src/fseccomp/errno.c b/src/fseccomp/errno.c
deleted file mode 100644
index 9c5aa770c..000000000
--- a/src/fseccomp/errno.c
+++ /dev/null
@@ -1,204 +0,0 @@
1/*
2 * Copyright (C) 2014-2020 Firejail Authors
3 *
4 * This file is part of firejail project
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License along
17 * with this program; if not, write to the Free Software Foundation, Inc.,
18 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
19*/
20#include "fseccomp.h"
21
22#include <errno.h>
23//#include <attr/xattr.h>
24
25typedef struct {
26 char *name;
27 int nr;
28} ErrnoEntry;
29
30static ErrnoEntry errnolist[] = {
31//
32// code generated using tools/extract-errnos
33//
34 {"EPERM", EPERM},
35 {"ENOENT", ENOENT},
36 {"ESRCH", ESRCH},
37 {"EINTR", EINTR},
38 {"EIO", EIO},
39 {"ENXIO", ENXIO},
40 {"E2BIG", E2BIG},
41 {"ENOEXEC", ENOEXEC},
42 {"EBADF", EBADF},
43 {"ECHILD", ECHILD},
44 {"EAGAIN", EAGAIN},
45 {"ENOMEM", ENOMEM},
46 {"EACCES", EACCES},
47 {"EFAULT", EFAULT},
48 {"ENOTBLK", ENOTBLK},
49 {"EBUSY", EBUSY},
50 {"EEXIST", EEXIST},
51 {"EXDEV", EXDEV},
52 {"ENODEV", ENODEV},
53 {"ENOTDIR", ENOTDIR},
54 {"EISDIR", EISDIR},
55 {"EINVAL", EINVAL},
56 {"ENFILE", ENFILE},
57 {"EMFILE", EMFILE},
58 {"ENOTTY", ENOTTY},
59 {"ETXTBSY", ETXTBSY},
60 {"EFBIG", EFBIG},
61 {"ENOSPC", ENOSPC},
62 {"ESPIPE", ESPIPE},
63 {"EROFS", EROFS},
64 {"EMLINK", EMLINK},
65 {"EPIPE", EPIPE},
66 {"EDOM", EDOM},
67 {"ERANGE", ERANGE},
68 {"EDEADLK", EDEADLK},
69 {"ENAMETOOLONG", ENAMETOOLONG},
70 {"ENOLCK", ENOLCK},
71 {"ENOSYS", ENOSYS},
72 {"ENOTEMPTY", ENOTEMPTY},
73 {"ELOOP", ELOOP},
74 {"EWOULDBLOCK", EWOULDBLOCK},
75 {"ENOMSG", ENOMSG},
76 {"EIDRM", EIDRM},
77 {"ECHRNG", ECHRNG},
78 {"EL2NSYNC", EL2NSYNC},
79 {"EL3HLT", EL3HLT},
80 {"EL3RST", EL3RST},
81 {"ELNRNG", ELNRNG},
82 {"EUNATCH", EUNATCH},
83 {"ENOCSI", ENOCSI},
84 {"EL2HLT", EL2HLT},
85 {"EBADE", EBADE},
86 {"EBADR", EBADR},
87 {"EXFULL", EXFULL},
88 {"ENOANO", ENOANO},
89 {"EBADRQC", EBADRQC},
90 {"EBADSLT", EBADSLT},
91 {"EDEADLOCK", EDEADLOCK},
92 {"EBFONT", EBFONT},
93 {"ENOSTR", ENOSTR},
94 {"ENODATA", ENODATA},
95 {"ETIME", ETIME},
96 {"ENOSR", ENOSR},
97 {"ENONET", ENONET},
98 {"ENOPKG", ENOPKG},
99 {"EREMOTE", EREMOTE},
100 {"ENOLINK", ENOLINK},
101 {"EADV", EADV},
102 {"ESRMNT", ESRMNT},
103 {"ECOMM", ECOMM},
104 {"EPROTO", EPROTO},
105 {"EMULTIHOP", EMULTIHOP},
106 {"EDOTDOT", EDOTDOT},
107 {"EBADMSG", EBADMSG},
108 {"EOVERFLOW", EOVERFLOW},
109 {"ENOTUNIQ", ENOTUNIQ},
110 {"EBADFD", EBADFD},
111 {"EREMCHG", EREMCHG},
112 {"ELIBACC", ELIBACC},
113 {"ELIBBAD", ELIBBAD},
114 {"ELIBSCN", ELIBSCN},
115 {"ELIBMAX", ELIBMAX},
116 {"ELIBEXEC", ELIBEXEC},
117 {"EILSEQ", EILSEQ},
118 {"ERESTART", ERESTART},
119 {"ESTRPIPE", ESTRPIPE},
120 {"EUSERS", EUSERS},
121 {"ENOTSOCK", ENOTSOCK},
122 {"EDESTADDRREQ", EDESTADDRREQ},
123 {"EMSGSIZE", EMSGSIZE},
124 {"EPROTOTYPE", EPROTOTYPE},
125 {"ENOPROTOOPT", ENOPROTOOPT},
126 {"EPROTONOSUPPORT", EPROTONOSUPPORT},
127 {"ESOCKTNOSUPPORT", ESOCKTNOSUPPORT},
128 {"EOPNOTSUPP", EOPNOTSUPP},
129 {"EPFNOSUPPORT", EPFNOSUPPORT},
130 {"EAFNOSUPPORT", EAFNOSUPPORT},
131 {"EADDRINUSE", EADDRINUSE},
132 {"EADDRNOTAVAIL", EADDRNOTAVAIL},
133 {"ENETDOWN", ENETDOWN},
134 {"ENETUNREACH", ENETUNREACH},
135 {"ENETRESET", ENETRESET},
136 {"ECONNABORTED", ECONNABORTED},
137 {"ECONNRESET", ECONNRESET},
138 {"ENOBUFS", ENOBUFS},
139 {"EISCONN", EISCONN},
140 {"ENOTCONN", ENOTCONN},
141 {"ESHUTDOWN", ESHUTDOWN},
142 {"ETOOMANYREFS", ETOOMANYREFS},
143 {"ETIMEDOUT", ETIMEDOUT},
144 {"ECONNREFUSED", ECONNREFUSED},
145 {"EHOSTDOWN", EHOSTDOWN},
146 {"EHOSTUNREACH", EHOSTUNREACH},
147 {"EALREADY", EALREADY},
148 {"EINPROGRESS", EINPROGRESS},
149 {"ESTALE", ESTALE},
150 {"EUCLEAN", EUCLEAN},
151 {"ENOTNAM", ENOTNAM},
152 {"ENAVAIL", ENAVAIL},
153 {"EISNAM", EISNAM},
154 {"EREMOTEIO", EREMOTEIO},
155 {"EDQUOT", EDQUOT},
156 {"ENOMEDIUM", ENOMEDIUM},
157 {"EMEDIUMTYPE", EMEDIUMTYPE},
158 {"ECANCELED", ECANCELED},
159 {"ENOKEY", ENOKEY},
160 {"EKEYEXPIRED", EKEYEXPIRED},
161 {"EKEYREVOKED", EKEYREVOKED},
162 {"EKEYREJECTED", EKEYREJECTED},
163 {"EOWNERDEAD", EOWNERDEAD},
164 {"ENOTRECOVERABLE", ENOTRECOVERABLE},
165 {"ERFKILL", ERFKILL},
166 {"EHWPOISON", EHWPOISON},
167 {"ENOTSUP", ENOTSUP},
168#ifdef ENOATTR
169 {"ENOATTR", ENOATTR},
170#endif
171};
172
173int errno_find_name(const char *name) {
174 int i;
175 int elems = sizeof(errnolist) / sizeof(errnolist[0]);
176 for (i = 0; i < elems; i++) {
177 if (strcasecmp(name, errnolist[i].name) == 0)
178 return errnolist[i].nr;
179 }
180
181 return -1;
182}
183
184char *errno_find_nr(int nr) {
185 int i;
186 int elems = sizeof(errnolist) / sizeof(errnolist[0]);
187 for (i = 0; i < elems; i++) {
188 if (nr == errnolist[i].nr)
189 return errnolist[i].name;
190 }
191
192 return "unknown";
193}
194
195
196
197void errno_print(void) {
198 int i;
199 int elems = sizeof(errnolist) / sizeof(errnolist[0]);
200 for (i = 0; i < elems; i++) {
201 printf("%d\t- %s\n", errnolist[i].nr, errnolist[i].name);
202 }
203 printf("\n");
204}
diff --git a/src/fseccomp/fseccomp.h b/src/fseccomp/fseccomp.h
index bf55870f2..e8dd083b6 100644
--- a/src/fseccomp/fseccomp.h
+++ b/src/fseccomp/fseccomp.h
@@ -24,21 +24,11 @@
24#include <string.h> 24#include <string.h>
25#include <assert.h> 25#include <assert.h>
26#include "../include/common.h" 26#include "../include/common.h"
27#include "../include/syscall.h"
27 28
28// main.c 29// main.c
29extern int arg_quiet; 30extern int arg_quiet;
30 31
31// syscall.c
32void syscall_print(void);
33int syscall_check_list(const char *slist, void (*callback)(int fd, int syscall, int arg, void *ptrarg), int fd, int arg, void *ptrarg);
34const char *syscall_find_nr(int nr);
35void syscalls_in_list(const char *list, const char *slist, int fd, char **prelist, char **postlist);
36
37// errno.c
38void errno_print(void);
39int errno_find_name(const char *name);
40char *errno_find_nr(int nr);
41
42// protocol.c 32// protocol.c
43void protocol_print(void); 33void protocol_print(void);
44void protocol_build_filter(const char *prlist, const char *fname); 34void protocol_build_filter(const char *prlist, const char *fname);
@@ -49,27 +39,27 @@ void seccomp_secondary_32(const char *fname);
49void seccomp_secondary_block(const char *fname); 39void seccomp_secondary_block(const char *fname);
50 40
51// seccomp_file.c 41// seccomp_file.c
52void write_to_file(int fd, const void *data, int size); 42void write_to_file(int fd, const void *data, size_t size);
53void filter_init(int fd); 43void filter_init(int fd, bool native);
54void filter_add_whitelist(int fd, int syscall, int arg, void *ptrarg); 44void filter_add_whitelist(int fd, int syscall, int arg, void *ptrarg, bool native);
55void filter_add_whitelist_for_excluded(int fd, int syscall, int arg, void *ptrarg); 45void filter_add_whitelist_for_excluded(int fd, int syscall, int arg, void *ptrarg, bool native);
56void filter_add_blacklist(int fd, int syscall, int arg, void *ptrarg); 46void filter_add_blacklist(int fd, int syscall, int arg, void *ptrarg, bool native);
57void filter_add_blacklist_for_excluded(int fd, int syscall, int arg, void *ptrarg); 47void filter_add_blacklist_for_excluded(int fd, int syscall, int arg, void *ptrarg, bool native);
58void filter_add_errno(int fd, int syscall, int arg, void *ptrarg);
59void filter_end_blacklist(int fd); 48void filter_end_blacklist(int fd);
60void filter_end_whitelist(int fd); 49void filter_end_whitelist(int fd);
61 50
62// seccomp.c 51// seccomp.c
63// default list 52// default list
64void seccomp_default(const char *fname, int allow_debuggers); 53void seccomp_default(const char *fname, int allow_debuggers, bool native);
65// drop list 54// drop list
66void seccomp_drop(const char *fname1, const char *fname2, char *list, int allow_debuggers); 55void seccomp_drop(const char *fname1, const char *fname2, char *list, int allow_debuggers, bool native);
67// default+drop list 56// default+drop list
68void seccomp_default_drop(const char *fname1, const char *fname2, char *list, int allow_debuggers); 57void seccomp_default_drop(const char *fname1, const char *fname2, char *list, int allow_debuggers, bool native);
69// whitelisted filter 58// whitelisted filter
70void seccomp_keep(const char *fname1, const char *fname2, char *list); 59void seccomp_keep(const char *fname1, const char *fname2, char *list, bool native);
71// block writable and executable memory 60// block writable and executable memory
72void memory_deny_write_execute(const char *fname); 61void memory_deny_write_execute(const char *fname);
62void memory_deny_write_execute_32(const char *fname);
73 63
74// seccomp_print 64// seccomp_print
75void filter_print(const char *fname); 65void filter_print(const char *fname);
diff --git a/src/fseccomp/main.c b/src/fseccomp/main.c
index 82b96f476..b3161a6db 100644
--- a/src/fseccomp/main.c
+++ b/src/fseccomp/main.c
@@ -23,6 +23,7 @@ int arg_quiet = 0;
23static void usage(void) { 23static void usage(void) {
24 printf("Usage:\n"); 24 printf("Usage:\n");
25 printf("\tfseccomp debug-syscalls\n"); 25 printf("\tfseccomp debug-syscalls\n");
26 printf("\tfseccomp debug-syscalls32\n");
26 printf("\tfseccomp debug-errnos\n"); 27 printf("\tfseccomp debug-errnos\n");
27 printf("\tfseccomp debug-protocols\n"); 28 printf("\tfseccomp debug-protocols\n");
28 printf("\tfseccomp protocol build list file\n"); 29 printf("\tfseccomp protocol build list file\n");
@@ -31,12 +32,20 @@ static void usage(void) {
31 printf("\tfseccomp secondary block file\n"); 32 printf("\tfseccomp secondary block file\n");
32 printf("\tfseccomp default file\n"); 33 printf("\tfseccomp default file\n");
33 printf("\tfseccomp default file allow-debuggers\n"); 34 printf("\tfseccomp default file allow-debuggers\n");
35 printf("\tfseccomp default32 file\n");
36 printf("\tfseccomp default32 file allow-debuggers\n");
34 printf("\tfseccomp drop file1 file2 list\n"); 37 printf("\tfseccomp drop file1 file2 list\n");
35 printf("\tfseccomp drop file1 file2 list allow-debuggers\n"); 38 printf("\tfseccomp drop file1 file2 list allow-debuggers\n");
39 printf("\tfseccomp drop32 file1 file2 list\n");
40 printf("\tfseccomp drop32 file1 file2 list allow-debuggers\n");
36 printf("\tfseccomp default drop file1 file2 list\n"); 41 printf("\tfseccomp default drop file1 file2 list\n");
37 printf("\tfseccomp default drop file1 file2 list allow-debuggers\n"); 42 printf("\tfseccomp default drop file1 file2 list allow-debuggers\n");
43 printf("\tfseccomp default32 drop file1 file2 list\n");
44 printf("\tfseccomp default32 drop file1 file2 list allow-debuggers\n");
38 printf("\tfseccomp keep file1 file2 list\n"); 45 printf("\tfseccomp keep file1 file2 list\n");
46 printf("\tfseccomp keep32 file1 file2 list\n");
39 printf("\tfseccomp memory-deny-write-execute file\n"); 47 printf("\tfseccomp memory-deny-write-execute file\n");
48 printf("\tfseccomp memory-deny-write-execute.32 file\n");
40} 49}
41 50
42int main(int argc, char **argv) { 51int main(int argc, char **argv) {
@@ -64,6 +73,8 @@ printf("\n");
64 } 73 }
65 else if (argc == 2 && strcmp(argv[1], "debug-syscalls") == 0) 74 else if (argc == 2 && strcmp(argv[1], "debug-syscalls") == 0)
66 syscall_print(); 75 syscall_print();
76 else if (argc == 2 && strcmp(argv[1], "debug-syscalls32") == 0)
77 syscall_print_32();
67 else if (argc == 2 && strcmp(argv[1], "debug-errnos") == 0) 78 else if (argc == 2 && strcmp(argv[1], "debug-errnos") == 0)
68 errno_print(); 79 errno_print();
69 else if (argc == 2 && strcmp(argv[1], "debug-protocols") == 0) 80 else if (argc == 2 && strcmp(argv[1], "debug-protocols") == 0)
@@ -75,21 +86,37 @@ printf("\n");
75 else if (argc == 4 && strcmp(argv[1], "secondary") == 0 && strcmp(argv[2], "block") == 0) 86 else if (argc == 4 && strcmp(argv[1], "secondary") == 0 && strcmp(argv[2], "block") == 0)
76 seccomp_secondary_block(argv[3]); 87 seccomp_secondary_block(argv[3]);
77 else if (argc == 3 && strcmp(argv[1], "default") == 0) 88 else if (argc == 3 && strcmp(argv[1], "default") == 0)
78 seccomp_default(argv[2], 0); 89 seccomp_default(argv[2], 0, true);
79 else if (argc == 4 && strcmp(argv[1], "default") == 0 && strcmp(argv[3], "allow-debuggers") == 0) 90 else if (argc == 4 && strcmp(argv[1], "default") == 0 && strcmp(argv[3], "allow-debuggers") == 0)
80 seccomp_default(argv[2], 1); 91 seccomp_default(argv[2], 1, true);
92 else if (argc == 3 && strcmp(argv[1], "default32") == 0)
93 seccomp_default(argv[2], 0, false);
94 else if (argc == 4 && strcmp(argv[1], "default32") == 0 && strcmp(argv[3], "allow-debuggers") == 0)
95 seccomp_default(argv[2], 1, false);
81 else if (argc == 5 && strcmp(argv[1], "drop") == 0) 96 else if (argc == 5 && strcmp(argv[1], "drop") == 0)
82 seccomp_drop(argv[2], argv[3], argv[4], 0); 97 seccomp_drop(argv[2], argv[3], argv[4], 0, true);
83 else if (argc == 6 && strcmp(argv[1], "drop") == 0 && strcmp(argv[5], "allow-debuggers") == 0) 98 else if (argc == 6 && strcmp(argv[1], "drop") == 0 && strcmp(argv[5], "allow-debuggers") == 0)
84 seccomp_drop(argv[2], argv[3], argv[4], 1); 99 seccomp_drop(argv[2], argv[3], argv[4], 1, true);
100 else if (argc == 5 && strcmp(argv[1], "drop32") == 0)
101 seccomp_drop(argv[2], argv[3], argv[4], 0, false);
102 else if (argc == 6 && strcmp(argv[1], "drop32") == 0 && strcmp(argv[5], "allow-debuggers") == 0)
103 seccomp_drop(argv[2], argv[3], argv[4], 1, false);
85 else if (argc == 6 && strcmp(argv[1], "default") == 0 && strcmp(argv[2], "drop") == 0) 104 else if (argc == 6 && strcmp(argv[1], "default") == 0 && strcmp(argv[2], "drop") == 0)
86 seccomp_default_drop(argv[3], argv[4], argv[5], 0); 105 seccomp_default_drop(argv[3], argv[4], argv[5], 0, true);
87 else if (argc == 7 && strcmp(argv[1], "default") == 0 && strcmp(argv[2], "drop") == 0 && strcmp(argv[6], "allow-debuggers") == 0) 106 else if (argc == 7 && strcmp(argv[1], "default") == 0 && strcmp(argv[2], "drop") == 0 && strcmp(argv[6], "allow-debuggers") == 0)
88 seccomp_default_drop(argv[3], argv[4], argv[5], 1); 107 seccomp_default_drop(argv[3], argv[4], argv[5], 1, true);
108 else if (argc == 6 && strcmp(argv[1], "default32") == 0 && strcmp(argv[2], "drop") == 0)
109 seccomp_default_drop(argv[3], argv[4], argv[5], 0, false);
110 else if (argc == 7 && strcmp(argv[1], "default32") == 0 && strcmp(argv[2], "drop") == 0 && strcmp(argv[6], "allow-debuggers") == 0)
111 seccomp_default_drop(argv[3], argv[4], argv[5], 1, false);
89 else if (argc == 5 && strcmp(argv[1], "keep") == 0) 112 else if (argc == 5 && strcmp(argv[1], "keep") == 0)
90 seccomp_keep(argv[2], argv[3], argv[4]); 113 seccomp_keep(argv[2], argv[3], argv[4], true);
114 else if (argc == 5 && strcmp(argv[1], "keep32") == 0)
115 seccomp_keep(argv[2], argv[3], argv[4], false);
91 else if (argc == 3 && strcmp(argv[1], "memory-deny-write-execute") == 0) 116 else if (argc == 3 && strcmp(argv[1], "memory-deny-write-execute") == 0)
92 memory_deny_write_execute(argv[2]); 117 memory_deny_write_execute(argv[2]);
118 else if (argc == 3 && strcmp(argv[1], "memory-deny-write-execute.32") == 0)
119 memory_deny_write_execute_32(argv[2]);
93 else { 120 else {
94 fprintf(stderr, "Error fseccomp: invalid arguments\n"); 121 fprintf(stderr, "Error fseccomp: invalid arguments\n");
95 return 1; 122 return 1;
diff --git a/src/fseccomp/protocol.c b/src/fseccomp/protocol.c
index 7a21eb2c2..b8b30f488 100644
--- a/src/fseccomp/protocol.c
+++ b/src/fseccomp/protocol.c
@@ -122,10 +122,23 @@ void protocol_build_filter(const char *prlist, const char *fname) {
122 122
123 // header 123 // header
124 struct sock_filter filter_start[] = { 124 struct sock_filter filter_start[] = {
125 VALIDATE_ARCHITECTURE, 125#if defined __x86_64__
126 EXAMINE_SYSCALL, 126 /* check for native arch */
127 ONLY(SYS_socket), 127 BPF_STMT(BPF_LD+BPF_W+BPF_ABS, (offsetof(struct seccomp_data, arch))),
128 EXAMINE_ARGUMENT(0) 128 BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, ARCH_NR, 1 + 2 + 1, 0),
129 /* i386 filter */
130 EXAMINE_SYSCALL, // 1
131 // checking SYS_socket only: filtering SYS_socketcall not possible with seccomp
132 ONLY(359), // 1 + 2
133 BPF_JUMP(BPF_JMP+BPF_JA+BPF_K, (3 + 1 + 2), 0, 0), // 1 + 2 + 1
134#else
135#warning 32 bit protocol filter not implemented yet for your architecture
136#endif
137 VALIDATE_ARCHITECTURE, // 3
138 EXAMINE_SYSCALL, // 3 + 1
139 ONLY(SYS_socket), // 3 + 1 + 2
140
141 EXAMINE_ARGUMENT(0) // 3 + 1 + 2 + 1
129 }; 142 };
130 memcpy(ptr, &filter_start[0], sizeof(filter_start)); 143 memcpy(ptr, &filter_start[0], sizeof(filter_start));
131 ptr += sizeof(filter_start); 144 ptr += sizeof(filter_start);
diff --git a/src/fseccomp/seccomp.c b/src/fseccomp/seccomp.c
index 29aa2f2f5..0db7b5954 100644
--- a/src/fseccomp/seccomp.c
+++ b/src/fseccomp/seccomp.c
@@ -24,12 +24,12 @@
24#include <sys/syscall.h> 24#include <sys/syscall.h>
25#include <sys/types.h> 25#include <sys/types.h>
26 26
27static void add_default_list(int fd, int allow_debuggers) { 27static void add_default_list(int fd, int allow_debuggers, bool native) {
28 int r; 28 int r;
29 if (!allow_debuggers) 29 if (!allow_debuggers)
30 r = syscall_check_list("@default-nodebuggers", filter_add_blacklist, fd, 0, NULL); 30 r = syscall_check_list("@default-nodebuggers", filter_add_blacklist, fd, 0, NULL, native);
31 else 31 else
32 r = syscall_check_list("@default", filter_add_blacklist, fd, 0, NULL); 32 r = syscall_check_list("@default", filter_add_blacklist, fd, 0, NULL, native);
33 33
34 assert(r == 0); 34 assert(r == 0);
35//#ifdef SYS_mknod - emoved in 0.9.29 - it breaks Zotero extension 35//#ifdef SYS_mknod - emoved in 0.9.29 - it breaks Zotero extension
@@ -46,7 +46,7 @@ static void add_default_list(int fd, int allow_debuggers) {
46} 46}
47 47
48// default list 48// default list
49void seccomp_default(const char *fname, int allow_debuggers) { 49void seccomp_default(const char *fname, int allow_debuggers, bool native) {
50 assert(fname); 50 assert(fname);
51 51
52 // open file 52 // open file
@@ -57,8 +57,8 @@ void seccomp_default(const char *fname, int allow_debuggers) {
57 } 57 }
58 58
59 // build filter (no post-exec filter needed because default list is fine for us) 59 // build filter (no post-exec filter needed because default list is fine for us)
60 filter_init(fd); 60 filter_init(fd, native);
61 add_default_list(fd, allow_debuggers); 61 add_default_list(fd, allow_debuggers, native);
62 filter_end_blacklist(fd); 62 filter_end_blacklist(fd);
63 63
64 // close file 64 // close file
@@ -66,7 +66,7 @@ void seccomp_default(const char *fname, int allow_debuggers) {
66} 66}
67 67
68// drop list 68// drop list
69void seccomp_drop(const char *fname1, const char *fname2, char *list, int allow_debuggers) { 69void seccomp_drop(const char *fname1, const char *fname2, char *list, int allow_debuggers, bool native) {
70 assert(fname1); 70 assert(fname1);
71 assert(fname2); 71 assert(fname2);
72 (void) allow_debuggers; // todo: to implemnet it 72 (void) allow_debuggers; // todo: to implemnet it
@@ -79,15 +79,15 @@ void seccomp_drop(const char *fname1, const char *fname2, char *list, int allow_
79 } 79 }
80 80
81 // build pre-exec filter: don't blacklist any syscalls in @default-keep 81 // build pre-exec filter: don't blacklist any syscalls in @default-keep
82 filter_init(fd); 82 filter_init(fd, native);
83 83
84 // allow exceptions in form of !syscall 84 // allow exceptions in form of !syscall
85 syscall_check_list(list, filter_add_whitelist_for_excluded, fd, 0, NULL); 85 syscall_check_list(list, filter_add_whitelist_for_excluded, fd, 0, NULL, native);
86 86
87 char *prelist, *postlist; 87 char *prelist, *postlist;
88 syscalls_in_list(list, "@default-keep", fd, &prelist, &postlist); 88 syscalls_in_list(list, "@default-keep", fd, &prelist, &postlist, native);
89 if (prelist) 89 if (prelist)
90 if (syscall_check_list(prelist, filter_add_blacklist, fd, 0, NULL)) { 90 if (syscall_check_list(prelist, filter_add_blacklist, fd, 0, NULL, native)) {
91 fprintf(stderr, "Error fseccomp: cannot build seccomp filter\n"); 91 fprintf(stderr, "Error fseccomp: cannot build seccomp filter\n");
92 exit(1); 92 exit(1);
93 } 93 }
@@ -106,8 +106,8 @@ void seccomp_drop(const char *fname1, const char *fname2, char *list, int allow_
106 } 106 }
107 107
108 // build post-exec filter: blacklist remaining syscalls 108 // build post-exec filter: blacklist remaining syscalls
109 filter_init(fd); 109 filter_init(fd, native);
110 if (syscall_check_list(postlist, filter_add_blacklist, fd, 0, NULL)) { 110 if (syscall_check_list(postlist, filter_add_blacklist, fd, 0, NULL, native)) {
111 fprintf(stderr, "Error fseccomp: cannot build seccomp filter\n"); 111 fprintf(stderr, "Error fseccomp: cannot build seccomp filter\n");
112 exit(1); 112 exit(1);
113 } 113 }
@@ -118,7 +118,7 @@ void seccomp_drop(const char *fname1, const char *fname2, char *list, int allow_
118} 118}
119 119
120// default+drop 120// default+drop
121void seccomp_default_drop(const char *fname1, const char *fname2, char *list, int allow_debuggers) { 121void seccomp_default_drop(const char *fname1, const char *fname2, char *list, int allow_debuggers, bool native) {
122 assert(fname1); 122 assert(fname1);
123 assert(fname2); 123 assert(fname2);
124 124
@@ -131,16 +131,16 @@ void seccomp_default_drop(const char *fname1, const char *fname2, char *list, in
131 131
132 // build pre-exec filter: blacklist @default, don't blacklist 132 // build pre-exec filter: blacklist @default, don't blacklist
133 // any listed syscalls in @default-keep 133 // any listed syscalls in @default-keep
134 filter_init(fd); 134 filter_init(fd, native);
135 135
136 // allow exceptions in form of !syscall 136 // allow exceptions in form of !syscall
137 syscall_check_list(list, filter_add_whitelist_for_excluded, fd, 0, NULL); 137 syscall_check_list(list, filter_add_whitelist_for_excluded, fd, 0, NULL, native);
138 138
139 add_default_list(fd, allow_debuggers); 139 add_default_list(fd, allow_debuggers, native);
140 char *prelist, *postlist; 140 char *prelist, *postlist;
141 syscalls_in_list(list, "@default-keep", fd, &prelist, &postlist); 141 syscalls_in_list(list, "@default-keep", fd, &prelist, &postlist, native);
142 if (prelist) 142 if (prelist)
143 if (syscall_check_list(prelist, filter_add_blacklist, fd, 0, NULL)) { 143 if (syscall_check_list(prelist, filter_add_blacklist, fd, 0, NULL, native)) {
144 fprintf(stderr, "Error fseccomp: cannot build seccomp filter\n"); 144 fprintf(stderr, "Error fseccomp: cannot build seccomp filter\n");
145 exit(1); 145 exit(1);
146 } 146 }
@@ -160,8 +160,8 @@ void seccomp_default_drop(const char *fname1, const char *fname2, char *list, in
160 } 160 }
161 161
162 // build post-exec filter: blacklist remaining syscalls 162 // build post-exec filter: blacklist remaining syscalls
163 filter_init(fd); 163 filter_init(fd, native);
164 if (syscall_check_list(postlist, filter_add_blacklist, fd, 0, NULL)) { 164 if (syscall_check_list(postlist, filter_add_blacklist, fd, 0, NULL, native)) {
165 fprintf(stderr, "Error fseccomp: cannot build seccomp filter\n"); 165 fprintf(stderr, "Error fseccomp: cannot build seccomp filter\n");
166 exit(1); 166 exit(1);
167 } 167 }
@@ -171,7 +171,7 @@ void seccomp_default_drop(const char *fname1, const char *fname2, char *list, in
171 close(fd); 171 close(fd);
172} 172}
173 173
174void seccomp_keep(const char *fname1, const char *fname2, char *list) { 174void seccomp_keep(const char *fname1, const char *fname2, char *list, bool native) {
175 (void) fname2; 175 (void) fname2;
176 176
177 // open file for pre-exec filter 177 // open file for pre-exec filter
@@ -182,17 +182,17 @@ void seccomp_keep(const char *fname1, const char *fname2, char *list) {
182 } 182 }
183 183
184 // build pre-exec filter: whitelist also @default-keep 184 // build pre-exec filter: whitelist also @default-keep
185 filter_init(fd); 185 filter_init(fd, native);
186 186
187 // allow exceptions in form of !syscall 187 // allow exceptions in form of !syscall
188 syscall_check_list(list, filter_add_blacklist_for_excluded, fd, 0, NULL); 188 syscall_check_list(list, filter_add_blacklist_for_excluded, fd, 0, NULL, native);
189 189
190 // these syscalls are used by firejail after the seccomp filter is initialized 190 // these syscalls are used by firejail after the seccomp filter is initialized
191 int r; 191 int r;
192 r = syscall_check_list("@default-keep", filter_add_whitelist, fd, 0, NULL); 192 r = syscall_check_list("@default-keep", filter_add_whitelist, fd, 0, NULL, native);
193 assert(r == 0); 193 assert(r == 0);
194 194
195 if (syscall_check_list(list, filter_add_whitelist, fd, 0, NULL)) { 195 if (syscall_check_list(list, filter_add_whitelist, fd, 0, NULL, native)) {
196 fprintf(stderr, "Error fseccomp: cannot build seccomp filter\n"); 196 fprintf(stderr, "Error fseccomp: cannot build seccomp filter\n");
197 exit(1); 197 exit(1);
198 } 198 }
@@ -206,6 +206,15 @@ void seccomp_keep(const char *fname1, const char *fname2, char *list) {
206#if defined(__x86_64__) || defined(__aarch64__) || defined(__powerpc64__) 206#if defined(__x86_64__) || defined(__aarch64__) || defined(__powerpc64__)
207# define filter_syscall SYS_mmap 207# define filter_syscall SYS_mmap
208# undef block_syscall 208# undef block_syscall
209#if defined(__x86_64__)
210// i386 syscalls
211# define filter_syscall_32 192
212# define block_syscall_32 90
213# define mprotect_32 125
214# define pkey_mprotect_32 380
215# define shmat_32 397
216# define memfd_create_32 356
217#endif
209#elif defined(__i386__) 218#elif defined(__i386__)
210# define filter_syscall SYS_mmap2 219# define filter_syscall SYS_mmap2
211# define block_syscall SYS_mmap 220# define block_syscall SYS_mmap
@@ -216,6 +225,12 @@ void seccomp_keep(const char *fname1, const char *fname2, char *list) {
216# warning "Platform does not support seccomp memory-deny-write-execute filter yet" 225# warning "Platform does not support seccomp memory-deny-write-execute filter yet"
217# undef filter_syscall 226# undef filter_syscall
218# undef block_syscall 227# undef block_syscall
228# undef filter_syscall_32
229# undef block_syscall_32
230# undef mprotect_32
231# undef pkey_mprotect_32
232# undef shmat_32
233# undef memfd_create_32
219#endif 234#endif
220 235
221void memory_deny_write_execute(const char *fname) { 236void memory_deny_write_execute(const char *fname) {
@@ -226,10 +241,10 @@ void memory_deny_write_execute(const char *fname) {
226 exit(1); 241 exit(1);
227 } 242 }
228 243
229 filter_init(fd); 244 filter_init(fd, true);
230 245
231 // build filter 246 // build filter
232 static const struct sock_filter filter[] = { 247 struct sock_filter filter[] = {
233#ifdef block_syscall 248#ifdef block_syscall
234 // block old multiplexing mmap syscall for i386 249 // block old multiplexing mmap syscall for i386
235 BLACKLIST(block_syscall), 250 BLACKLIST(block_syscall),
@@ -288,3 +303,75 @@ void memory_deny_write_execute(const char *fname) {
288 // close file 303 // close file
289 close(fd); 304 close(fd);
290} 305}
306
307void memory_deny_write_execute_32(const char *fname) {
308 // open file
309 int fd = open(fname, O_CREAT|O_WRONLY|O_TRUNC, S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH);
310 if (fd < 0) {
311 fprintf(stderr, "Error fseccomp: cannot open %s file\n", fname);
312 exit(1);
313 }
314
315 filter_init(fd, false);
316
317 // build filter
318 struct sock_filter filter[] = {
319#if defined(__x86_64__)
320#ifdef block_syscall_32
321 // block old multiplexing mmap syscall for i386
322 BLACKLIST(block_syscall_32),
323#endif
324#ifdef filter_syscall_32
325 // block mmap(,,x|PROT_WRITE|PROT_EXEC) so W&X memory can't be created
326 BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, filter_syscall_32, 0, 5),
327 EXAMINE_ARGUMENT(2),
328 BPF_STMT(BPF_ALU+BPF_AND+BPF_K, PROT_WRITE|PROT_EXEC),
329 BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, PROT_WRITE|PROT_EXEC, 0, 1),
330 KILL_PROCESS,
331 RETURN_ALLOW,
332#endif
333#ifdef mprotect_32
334 // block mprotect(,,PROT_EXEC) so writable memory can't be turned into executable
335 BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, mprotect_32, 0, 5),
336 EXAMINE_ARGUMENT(2),
337 BPF_STMT(BPF_ALU+BPF_AND+BPF_K, PROT_EXEC),
338 BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, PROT_EXEC, 0, 1),
339 KILL_PROCESS,
340 RETURN_ALLOW,
341#endif
342#ifdef pkey_mprotect_32
343 // same for pkey_mprotect(,,PROT_EXEC), where available
344 BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, pkey_mprotect_32, 0, 5),
345 EXAMINE_ARGUMENT(2),
346 BPF_STMT(BPF_ALU+BPF_AND+BPF_K, PROT_EXEC),
347 BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, PROT_EXEC, 0, 1),
348 KILL_PROCESS,
349 RETURN_ALLOW,
350#endif
351
352#ifdef shmat_32
353 // block shmat(,,x|SHM_EXEC) so W&X shared memory can't be created
354 BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, shmat_32, 0, 5),
355 EXAMINE_ARGUMENT(2),
356 BPF_STMT(BPF_ALU+BPF_AND+BPF_K, SHM_EXEC),
357 BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, SHM_EXEC, 0, 1),
358 KILL_PROCESS,
359 RETURN_ALLOW,
360#endif
361#ifdef memfd_create_32
362 // block memfd_create as it can be used to create
363 // arbitrary memory contents which can be later mapped
364 // as executable
365 BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, memfd_create_32, 0, 1),
366 KILL_PROCESS,
367#endif
368#endif
369 RETURN_ALLOW
370 };
371 write_to_file(fd, filter, sizeof(filter));
372
373 filter_end_blacklist(fd);
374
375 // close file
376 close(fd);
377}
diff --git a/src/fseccomp/seccomp_file.c b/src/fseccomp/seccomp_file.c
index e47e8db25..872b41261 100644
--- a/src/fseccomp/seccomp_file.c
+++ b/src/fseccomp/seccomp_file.c
@@ -21,11 +21,11 @@
21#include "../include/seccomp.h" 21#include "../include/seccomp.h"
22#include <sys/syscall.h> 22#include <sys/syscall.h>
23 23
24void write_to_file(int fd, const void *data, int size) { 24void write_to_file(int fd, const void *data, size_t size) {
25 assert(data); 25 assert(data);
26 assert(size); 26 assert(size);
27 27
28 int written = 0; 28 size_t written = 0;
29 while (written < size) { 29 while (written < size) {
30 int rv = write(fd, (unsigned char *) data + written, size - written); 30 int rv = write(fd, (unsigned char *) data + written, size - written);
31 if (rv == -1) { 31 if (rv == -1) {
@@ -36,8 +36,8 @@ void write_to_file(int fd, const void *data, int size) {
36 } 36 }
37} 37}
38 38
39void filter_init(int fd) { 39void filter_init(int fd, bool native) {
40 struct sock_filter filter[] = { 40 struct sock_filter filter_native[] = {
41 VALIDATE_ARCHITECTURE, 41 VALIDATE_ARCHITECTURE,
42#if defined(__x86_64__) 42#if defined(__x86_64__)
43 EXAMINE_SYSCALL, 43 EXAMINE_SYSCALL,
@@ -46,6 +46,10 @@ void filter_init(int fd) {
46 EXAMINE_SYSCALL 46 EXAMINE_SYSCALL
47#endif 47#endif
48 }; 48 };
49 struct sock_filter filter_32[] = {
50 VALIDATE_ARCHITECTURE_32,
51 EXAMINE_SYSCALL
52 };
49 53
50#if 0 54#if 0
51{ 55{
@@ -57,7 +61,10 @@ void filter_init(int fd) {
57} 61}
58#endif 62#endif
59 63
60 write_to_file(fd, filter, sizeof(filter)); 64 if (native)
65 write_to_file(fd, filter_native, sizeof(filter_native));
66 else
67 write_to_file(fd, filter_32, sizeof(filter_32));
61} 68}
62 69
63static void write_whitelist(int fd, int syscall) { 70static void write_whitelist(int fd, int syscall) {
@@ -74,9 +81,10 @@ static void write_blacklist(int fd, int syscall) {
74 write_to_file(fd, filter, sizeof(filter)); 81 write_to_file(fd, filter, sizeof(filter));
75} 82}
76 83
77void filter_add_whitelist(int fd, int syscall, int arg, void *ptrarg) { 84void filter_add_whitelist(int fd, int syscall, int arg, void *ptrarg, bool native) {
78 (void) arg; 85 (void) arg;
79 (void) ptrarg; 86 (void) ptrarg;
87 (void) native;
80 88
81 if (syscall >= 0) { 89 if (syscall >= 0) {
82 write_whitelist(fd, syscall); 90 write_whitelist(fd, syscall);
@@ -84,18 +92,20 @@ void filter_add_whitelist(int fd, int syscall, int arg, void *ptrarg) {
84} 92}
85 93
86// handle seccomp list exceptions (seccomp x,y,!z) 94// handle seccomp list exceptions (seccomp x,y,!z)
87void filter_add_whitelist_for_excluded(int fd, int syscall, int arg, void *ptrarg) { 95void filter_add_whitelist_for_excluded(int fd, int syscall, int arg, void *ptrarg, bool native) {
88 (void) arg; 96 (void) arg;
89 (void) ptrarg; 97 (void) ptrarg;
98 (void) native;
90 99
91 if (syscall < 0) { 100 if (syscall < 0) {
92 write_whitelist(fd, -syscall); 101 write_whitelist(fd, -syscall);
93 } 102 }
94} 103}
95 104
96void filter_add_blacklist(int fd, int syscall, int arg, void *ptrarg) { 105void filter_add_blacklist(int fd, int syscall, int arg, void *ptrarg, bool native) {
97 (void) arg; 106 (void) arg;
98 (void) ptrarg; 107 (void) ptrarg;
108 (void) native;
99 109
100 if (syscall >= 0) { 110 if (syscall >= 0) {
101 write_blacklist(fd, syscall); 111 write_blacklist(fd, syscall);
@@ -103,17 +113,20 @@ void filter_add_blacklist(int fd, int syscall, int arg, void *ptrarg) {
103} 113}
104 114
105// handle seccomp list exceptions (seccomp x,y,!z) 115// handle seccomp list exceptions (seccomp x,y,!z)
106void filter_add_blacklist_for_excluded(int fd, int syscall, int arg, void *ptrarg) { 116void filter_add_blacklist_for_excluded(int fd, int syscall, int arg, void *ptrarg, bool native) {
107 (void) arg; 117 (void) arg;
108 (void) ptrarg; 118 (void) ptrarg;
119 (void) native;
109 120
110 if (syscall < 0) { 121 if (syscall < 0) {
111 write_blacklist(fd, -syscall); 122 write_blacklist(fd, -syscall);
112 } 123 }
113} 124}
114 125
115void filter_add_errno(int fd, int syscall, int arg, void *ptrarg) { 126void filter_add_errno(int fd, int syscall, int arg, void *ptrarg, bool native) {
116 (void) ptrarg; 127 (void) ptrarg;
128 (void) native;
129
117 struct sock_filter filter[] = { 130 struct sock_filter filter[] = {
118 BLACKLIST_ERRNO(syscall, arg) 131 BLACKLIST_ERRNO(syscall, arg)
119 }; 132 };
diff --git a/src/fseccomp/syscall.c b/src/fseccomp/syscall.c
deleted file mode 100644
index 2b112245c..000000000
--- a/src/fseccomp/syscall.c
+++ /dev/null
@@ -1,1632 +0,0 @@
1/*
2 * Copyright (C) 2014-2020 Firejail Authors
3 *
4 * This file is part of firejail project
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License along
17 * with this program; if not, write to the Free Software Foundation, Inc.,
18 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
19*/
20#define _GNU_SOURCE
21#include "fseccomp.h"
22#include <stdio.h>
23#include <sys/syscall.h>
24
25typedef struct {
26 const char * const name;
27 int nr;
28} SyscallEntry;
29
30typedef struct {
31 const char * const name;
32 const char * const list;
33} SyscallGroupList;
34
35typedef struct {
36 const char *slist;
37 char *prelist, *postlist;
38 bool found;
39 int syscall;
40} SyscallCheckList;
41
42static const SyscallEntry syslist[] = {
43//
44// code generated using tools/extract-syscall
45//
46#include "../include/syscall.h"
47//
48// end of generated code
49//
50}; // end of syslist
51
52static const SyscallGroupList sysgroups[] = {
53 { .name = "@aio", .list =
54#ifdef SYS_io_cancel
55 "io_cancel,"
56#endif
57#ifdef SYS_io_destroy
58 "io_destroy,"
59#endif
60#ifdef SYS_io_getevents
61 "io_getevents,"
62#endif
63#ifdef SYS_io_pgetevents
64 "io_pgetevents,"
65#endif
66#ifdef SYS_io_setup
67 "io_setup,"
68#endif
69#ifdef SYS_io_submit
70 "io_submit"
71#endif
72 },
73 { .name = "@basic-io", .list =
74#ifdef SYS__llseek
75 "_llseek,"
76#endif
77#ifdef SYS_close
78 "close,"
79#endif
80#ifdef SYS_dup
81 "dup,"
82#endif
83#ifdef SYS_dup2
84 "dup2,"
85#endif
86#ifdef SYS_dup3
87 "dup3,"
88#endif
89#ifdef SYS_lseek
90 "lseek,"
91#endif
92#ifdef SYS_pread64
93 "pread64,"
94#endif
95#ifdef SYS_preadv
96 "preadv,"
97#endif
98#ifdef SYS_preadv2
99 "preadv2,"
100#endif
101#ifdef SYS_pwrite64
102 "pwrite64,"
103#endif
104#ifdef SYS_pwritev
105 "pwritev,"
106#endif
107#ifdef SYS_pwritev2
108 "pwritev2,"
109#endif
110#ifdef SYS_read
111 "read,"
112#endif
113#ifdef SYS_readv
114 "readv,"
115#endif
116#ifdef SYS_write
117 "write,"
118#endif
119#ifdef SYS_writev
120 "writev"
121#endif
122 },
123 { .name = "@chown", .list =
124#ifdef SYS_chown
125 "chown,"
126#endif
127#ifdef SYS_chown32
128 "chown32,"
129#endif
130#ifdef SYS_fchown
131 "fchown,"
132#endif
133#ifdef SYS_fchown32
134 "fchown32,"
135#endif
136#ifdef SYS_fchownat
137 "fchownat,"
138#endif
139#ifdef SYS_lchown
140 "lchown,"
141#endif
142#ifdef SYS_lchown32
143 "lchown32"
144#endif
145 },
146 { .name = "@clock", .list =
147#ifdef SYS_adjtimex
148 "adjtimex,"
149#endif
150#ifdef SYS_clock_adjtime
151 "clock_adjtime,"
152#endif
153#ifdef SYS_clock_settime
154 "clock_settime,"
155#endif
156#ifdef SYS_settimeofday
157 "settimeofday,"
158#endif
159#ifdef SYS_stime
160 "stime"
161#endif
162 },
163 { .name = "@cpu-emulation", .list =
164#ifdef SYS_modify_ldt
165 "modify_ldt,"
166#endif
167#ifdef SYS_subpage_prot
168 "subpage_prot,"
169#endif
170#ifdef SYS_switch_endian
171 "switch_endian,"
172#endif
173#ifdef SYS_vm86
174 "vm86,"
175#endif
176#ifdef SYS_vm86old
177 "vm86old"
178#endif
179#if !defined(SYS_modify_ldt) && !defined(SYS_subpage_prot) && !defined(SYS_switch_endian) && !defined(SYS_vm86) && !defined(SYS_vm86old)
180 "__dummy_syscall__" // workaround for arm64, s390x and sparc64 which don't have any of above defined and empty syscall lists are not allowed
181#endif
182 },
183 { .name = "@debug", .list =
184#ifdef SYS_lookup_dcookie
185 "lookup_dcookie,"
186#endif
187#ifdef SYS_perf_event_open
188 "perf_event_open,"
189#endif
190#ifdef SYS_process_vm_writev
191 "process_vm_writev,"
192#endif
193#ifdef SYS_rtas
194 "rtas,"
195#endif
196#ifdef SYS_s390_runtime_instr
197 "s390_runtime_instr,"
198#endif
199#ifdef SYS_sys_debug_setcontext
200 "sys_debug_setcontext,"
201#endif
202 },
203 { .name = "@default", .list =
204 "@clock,"
205 "@cpu-emulation,"
206 "@debug,"
207 "@module,"
208 "@obsolete,"
209 "@raw-io,"
210 "@reboot,"
211 "@swap,"
212#ifdef SYS_open_by_handle_at
213 "open_by_handle_at,"
214#endif
215#ifdef SYS_name_to_handle_at
216 "name_to_handle_at,"
217#endif
218#ifdef SYS_ioprio_set
219 "ioprio_set,"
220#endif
221#ifdef SYS_ni_syscall
222 "ni_syscall,"
223#endif
224#ifdef SYS_syslog
225 "syslog,"
226#endif
227#ifdef SYS_fanotify_init
228 "fanotify_init,"
229#endif
230#ifdef SYS_kcmp
231 "kcmp,"
232#endif
233#ifdef SYS_add_key
234 "add_key,"
235#endif
236#ifdef SYS_request_key
237 "request_key,"
238#endif
239#ifdef SYS_mbind
240 "mbind,"
241#endif
242#ifdef SYS_migrate_pages
243 "migrate_pages,"
244#endif
245#ifdef SYS_move_pages
246 "move_pages,"
247#endif
248#ifdef SYS_keyctl
249 "keyctl,"
250#endif
251#ifdef SYS_io_setup
252 "io_setup,"
253#endif
254#ifdef SYS_io_destroy
255 "io_destroy,"
256#endif
257#ifdef SYS_io_getevents
258 "io_getevents,"
259#endif
260#ifdef SYS_io_submit
261 "io_submit,"
262#endif
263#ifdef SYS_io_cancel
264 "io_cancel,"
265#endif
266#ifdef SYS_remap_file_pages
267 "remap_file_pages,"
268#endif
269#ifdef SYS_set_mempolicy
270 "set_mempolicy"
271#endif
272#ifdef SYS_vmsplice
273 "vmsplice,"
274#endif
275#ifdef SYS_umount
276 "umount,"
277#endif
278#ifdef SYS_userfaultfd
279 "userfaultfd,"
280#endif
281#ifdef SYS_acct
282 "acct,"
283#endif
284#ifdef SYS_bpf
285 "bpf,"
286#endif
287#ifdef SYS_chroot
288 "chroot,"
289#endif
290#ifdef SYS_mount
291 "mount,"
292#endif
293#ifdef SYS_nfsservctl
294 "nfsservctl,"
295#endif
296#ifdef SYS_pivot_root
297 "pivot_root,"
298#endif
299#ifdef SYS_setdomainname
300 "setdomainname,"
301#endif
302#ifdef SYS_sethostname
303 "sethostname,"
304#endif
305#ifdef SYS_umount2
306 "umount2,"
307#endif
308#ifdef SYS_vhangup
309 "vhangup"
310#endif
311//#ifdef SYS_mincore // 0.9.57 - problem fixed in Linux kernel 5.0; on 4.x it will break kodi, mpv, totem
312// "mincore"
313//#endif
314 },
315 { .name = "@default-nodebuggers", .list =
316 "@default,"
317#ifdef SYS_ptrace
318 "ptrace,"
319#endif
320#ifdef SYS_personality
321 "personality,"
322#endif
323#ifdef SYS_process_vm_readv
324 "process_vm_readv"
325#endif
326 },
327 { .name = "@default-keep", .list =
328 "execve,"
329 "prctl"
330 },
331 { .name = "@file-system", .list =
332#ifdef SYS_access
333 "access,"
334#endif
335#ifdef SYS_chdir
336 "chdir,"
337#endif
338#ifdef SYS_chmod
339 "chmod,"
340#endif
341#ifdef SYS_close
342 "close,"
343#endif
344#ifdef SYS_creat
345 "creat,"
346#endif
347#ifdef SYS_faccessat
348 "faccessat,"
349#endif
350#ifdef SYS_fallocate
351 "fallocate,"
352#endif
353#ifdef SYS_fchdir
354 "fchdir,"
355#endif
356#ifdef SYS_fchmod
357 "fchmod,"
358#endif
359#ifdef SYS_fchmodat
360 "fchmodat,"
361#endif
362#ifdef SYS_fcntl
363 "fcntl,"
364#endif
365#ifdef SYS_fcntl64
366 "fcntl64,"
367#endif
368#ifdef SYS_fgetxattr
369 "fgetxattr,"
370#endif
371#ifdef SYS_flistxattr
372 "flistxattr,"
373#endif
374#ifdef SYS_fremovexattr
375 "fremovexattr,"
376#endif
377#ifdef SYS_fsetxattr
378 "fsetxattr,"
379#endif
380#ifdef SYS_fstat
381 "fstat,"
382#endif
383#ifdef SYS_fstat64
384 "fstat64,"
385#endif
386#ifdef SYS_fstatat64
387 "fstatat64,"
388#endif
389#ifdef SYS_fstatfs
390 "fstatfs,"
391#endif
392#ifdef SYS_fstatfs64
393 "fstatfs64,"
394#endif
395#ifdef SYS_ftruncate
396 "ftruncate,"
397#endif
398#ifdef SYS_ftruncate64
399 "ftruncate64,"
400#endif
401#ifdef SYS_futimesat
402 "futimesat,"
403#endif
404#ifdef SYS_getcwd
405 "getcwd,"
406#endif
407#ifdef SYS_getdents
408 "getdents,"
409#endif
410#ifdef SYS_getdents64
411 "getdents64,"
412#endif
413#ifdef SYS_getxattr
414 "getxattr,"
415#endif
416#ifdef SYS_inotify_add_watch
417 "inotify_add_watch,"
418#endif
419#ifdef SYS_inotify_init
420 "inotify_init,"
421#endif
422#ifdef SYS_inotify_init1
423 "inotify_init1,"
424#endif
425#ifdef SYS_inotify_rm_watch
426 "inotify_rm_watch,"
427#endif
428#ifdef SYS_lgetxattr
429 "lgetxattr,"
430#endif
431#ifdef SYS_link
432 "link,"
433#endif
434#ifdef SYS_linkat
435 "linkat,"
436#endif
437#ifdef SYS_listxattr
438 "listxattr,"
439#endif
440#ifdef SYS_llistxattr
441 "llistxattr,"
442#endif
443#ifdef SYS_lremovexattr
444 "lremovexattr,"
445#endif
446#ifdef SYS_lsetxattr
447 "lsetxattr,"
448#endif
449#ifdef SYS_lstat
450 "lstat,"
451#endif
452#ifdef SYS_lstat64
453 "lstat64,"
454#endif
455#ifdef SYS_mkdir
456 "mkdir,"
457#endif
458#ifdef SYS_mkdirat
459 "mkdirat,"
460#endif
461#ifdef SYS_mknod
462 "mknod,"
463#endif
464#ifdef SYS_mknodat
465 "mknodat,"
466#endif
467#ifdef SYS_mmap
468 "mmap,"
469#endif
470#ifdef SYS_mmap2
471 "mmap2,"
472#endif
473#ifdef SYS_munmap
474 "munmap,"
475#endif
476#ifdef SYS_newfstatat
477 "newfstatat,"
478#endif
479#ifdef SYS_oldfstat
480 "oldfstat,"
481#endif
482#ifdef SYS_oldlstat
483 "oldlstat,"
484#endif
485#ifdef SYS_oldstat
486 "oldstat,"
487#endif
488#ifdef SYS_open
489 "open,"
490#endif
491#ifdef SYS_openat
492 "openat,"
493#endif
494#ifdef SYS_readlink
495 "readlink,"
496#endif
497#ifdef SYS_readlinkat
498 "readlinkat,"
499#endif
500#ifdef SYS_removexattr
501 "removexattr,"
502#endif
503#ifdef SYS_rename
504 "rename,"
505#endif
506#ifdef SYS_renameat
507 "renameat,"
508#endif
509#ifdef SYS_renameat2
510 "renameat2,"
511#endif
512#ifdef SYS_rmdir
513 "rmdir,"
514#endif
515#ifdef SYS_setxattr
516 "setxattr,"
517#endif
518#ifdef SYS_stat
519 "stat,"
520#endif
521#ifdef SYS_stat64
522 "stat64,"
523#endif
524#ifdef SYS_statfs
525 "statfs,"
526#endif
527#ifdef SYS_statfs64
528 "statfs64,"
529#endif
530#ifdef SYS_statx
531 "statx,"
532#endif
533#ifdef SYS_symlink
534 "symlink,"
535#endif
536#ifdef SYS_symlinkat
537 "symlinkat,"
538#endif
539#ifdef SYS_truncate
540 "truncate,"
541#endif
542#ifdef SYS_truncate64
543 "truncate64,"
544#endif
545#ifdef SYS_unlink
546 "unlink,"
547#endif
548#ifdef SYS_unlinkat
549 "unlinkat,"
550#endif
551#ifdef SYS_utime
552 "utime,"
553#endif
554#ifdef SYS_utimensat
555 "utimensat,"
556#endif
557#ifdef SYS_utimes
558 "utimes"
559#endif
560 },
561 { .name = "@io-event", .list =
562#ifdef SYS__newselect
563 "_newselect,"
564#endif
565#ifdef SYS_epoll_create
566 "epoll_create,"
567#endif
568#ifdef SYS_epoll_create1
569 "epoll_create1,"
570#endif
571#ifdef SYS_epoll_ctl
572 "epoll_ctl,"
573#endif
574#ifdef SYS_epoll_ctl_old
575 "epoll_ctl_old,"
576#endif
577#ifdef SYS_epoll_pwait
578 "epoll_pwait,"
579#endif
580#ifdef SYS_epoll_wait
581 "epoll_wait,"
582#endif
583#ifdef SYS_epoll_wait_old
584 "epoll_wait_old,"
585#endif
586#ifdef SYS_eventfd
587 "eventfd,"
588#endif
589#ifdef SYS_eventfd2
590 "eventfd2,"
591#endif
592#ifdef SYS_poll
593 "poll,"
594#endif
595#ifdef SYS_ppoll
596 "ppoll,"
597#endif
598#ifdef SYS_pselect6
599 "pselect6,"
600#endif
601#ifdef SYS_select
602 "select"
603#endif
604 },
605 { .name = "@ipc", .list =
606#ifdef SYS_ipc
607 "ipc,"
608#endif
609#ifdef SYS_memfd_create
610 "memfd_create,"
611#endif
612#ifdef SYS_mq_getsetattr
613 "mq_getsetattr,"
614#endif
615#ifdef SYS_mq_notify
616 "mq_notify,"
617#endif
618#ifdef SYS_mq_open
619 "mq_open,"
620#endif
621#ifdef SYS_mq_timedreceive
622 "mq_timedreceive,"
623#endif
624#ifdef SYS_mq_timedsend
625 "mq_timedsend,"
626#endif
627#ifdef SYS_mq_unlink
628 "mq_unlink,"
629#endif
630#ifdef SYS_msgctl
631 "msgctl,"
632#endif
633#ifdef SYS_msgget
634 "msgget,"
635#endif
636#ifdef SYS_msgrcv
637 "msgrcv,"
638#endif
639#ifdef SYS_msgsnd
640 "msgsnd,"
641#endif
642#ifdef SYS_pipe
643 "pipe,"
644#endif
645#ifdef SYS_pipe2
646 "pipe2,"
647#endif
648#ifdef SYS_process_vm_readv
649 "process_vm_readv,"
650#endif
651#ifdef SYS_process_vm_writev
652 "process_vm_writev,"
653#endif
654#ifdef SYS_semctl
655 "semctl,"
656#endif
657#ifdef SYS_semget
658 "semget,"
659#endif
660#ifdef SYS_semop
661 "semop,"
662#endif
663#ifdef SYS_semtimedop
664 "semtimedop,"
665#endif
666#ifdef SYS_shmat
667 "shmat,"
668#endif
669#ifdef SYS_shmctl
670 "shmctl,"
671#endif
672#ifdef SYS_shmdt
673 "shmdt,"
674#endif
675#ifdef SYS_shmget
676 "shmget"
677#endif
678 },
679 { .name = "@keyring", .list =
680#ifdef SYS_add_key
681 "add_key,"
682#endif
683#ifdef SYS_keyctl
684 "keyctl,"
685#endif
686#ifdef SYS_request_key
687 "request_key"
688#endif
689 },
690 { .name = "@memlock", .list =
691#ifdef SYS_mlock
692 "mlock,"
693#endif
694#ifdef SYS_mlock2
695 "mlock2,"
696#endif
697#ifdef SYS_mlockall
698 "mlockall,"
699#endif
700#ifdef SYS_munlock
701 "munlock,"
702#endif
703#ifdef SYS_munlockall
704 "munlockall"
705#endif
706 },
707 { .name = "@module", .list =
708#ifdef SYS_delete_module
709 "delete_module,"
710#endif
711#ifdef SYS_finit_module
712 "finit_module,"
713#endif
714#ifdef SYS_init_module
715 "init_module"
716#endif
717 },
718 { .name = "@mount", .list =
719#ifdef SYS_chroot
720 "chroot,"
721#endif
722#ifdef SYS_mount
723 "mount,"
724#endif
725#ifdef SYS_pivot_root
726 "pivot_root,"
727#endif
728#ifdef SYS_umount
729 "umount,"
730#endif
731#ifdef SYS_umount2
732 "umount2"
733#endif
734 },
735 { .name = "@network-io", .list =
736#ifdef SYS_accept
737 "accept,"
738#endif
739#ifdef SYS_accept4
740 "accept4,"
741#endif
742#ifdef SYS_bind
743 "bind,"
744#endif
745#ifdef SYS_connect
746 "connect,"
747#endif
748#ifdef SYS_getpeername
749 "getpeername,"
750#endif
751#ifdef SYS_getsockname
752 "getsockname,"
753#endif
754#ifdef SYS_getsockopt
755 "getsockopt,"
756#endif
757#ifdef SYS_listen
758 "listen,"
759#endif
760#ifdef SYS_recv
761 "recv,"
762#endif
763#ifdef SYS_recvfrom
764 "recvfrom,"
765#endif
766#ifdef SYS_recvmmsg
767 "recvmmsg,"
768#endif
769#ifdef SYS_recvmsg
770 "recvmsg,"
771#endif
772#ifdef SYS_send
773 "send,"
774#endif
775#ifdef SYS_sendmmsg
776 "sendmmsg,"
777#endif
778#ifdef SYS_sendmsg
779 "sendmsg,"
780#endif
781#ifdef SYS_sendto
782 "sendto,"
783#endif
784#ifdef SYS_setsockopt
785 "setsockopt,"
786#endif
787#ifdef SYS_shutdown
788 "shutdown,"
789#endif
790#ifdef SYS_socket
791 "socket,"
792#endif
793#ifdef SYS_socketcall
794 "socketcall,"
795#endif
796#ifdef SYS_socketpair
797 "socketpair"
798#endif
799 },
800 { .name = "@obsolete", .list =
801#ifdef SYS__sysctl
802 "_sysctl,"
803#endif
804#ifdef SYS_afs_syscall
805 "afs_syscall,"
806#endif
807#ifdef SYS_bdflush
808 "bdflush,"
809#endif
810#ifdef SYS_break
811 "break,"
812#endif
813#ifdef SYS_create_module
814 "create_module,"
815#endif
816#ifdef SYS_ftime
817 "ftime,"
818#endif
819#ifdef SYS_get_kernel_syms
820 "get_kernel_syms,"
821#endif
822#ifdef SYS_getpmsg
823 "getpmsg,"
824#endif
825#ifdef SYS_gtty
826 "gtty,"
827#endif
828#ifdef SYS_idle
829 "idle,"
830#endif
831#ifdef SYS_lock
832 "lock,"
833#endif
834#ifdef SYS_mpx
835 "mpx,"
836#endif
837#ifdef SYS_prof
838 "prof,"
839#endif
840#ifdef SYS_profil
841 "profil,"
842#endif
843#ifdef SYS_putpmsg
844 "putpmsg,"
845#endif
846#ifdef SYS_query_module
847 "query_module,"
848#endif
849#ifdef SYS_security
850 "security,"
851#endif
852#ifdef SYS_sgetmask
853 "sgetmask,"
854#endif
855#ifdef SYS_ssetmask
856 "ssetmask,"
857#endif
858#ifdef SYS_stty
859 "stty,"
860#endif
861#ifdef SYS_sysfs
862 "sysfs,"
863#endif
864#ifdef SYS_tuxcall
865 "tuxcall,"
866#endif
867#ifdef SYS_ulimit
868 "ulimit,"
869#endif
870#ifdef SYS_uselib
871 "uselib,"
872#endif
873#ifdef SYS_ustat
874 "ustat,"
875#endif
876#ifdef SYS_vserver
877 "vserver"
878#endif
879#if !defined(SYS__sysctl) && !defined(SYS_afs_syscall) && !defined(SYS_bdflush) && !defined(SYS_break) && !defined(SYS_create_module) && !defined(SYS_ftime) && !defined(SYS_get_kernel_syms) && !defined(SYS_getpmsg) && !defined(SYS_gtty) && !defined(SYS_lock) && !defined(SYS_mpx) && !defined(SYS_prof) && !defined(SYS_profil) && !defined(SYS_putpmsg) && !defined(SYS_query_module) && !defined(SYS_security) && !defined(SYS_sgetmask) && !defined(SYS_ssetmask) && !defined(SYS_stty) && !defined(SYS_sysfs) && !defined(SYS_tuxcall) && !defined(SYS_ulimit) && !defined(SYS_uselib) && !defined(SYS_ustat) && !defined(SYS_vserver)
880 "__dummy_syscall__" // workaround for arm64 which doesn't have any of above defined and empty syscall lists are not allowed
881#endif
882 },
883 { .name = "@privileged", .list =
884 "@chown,"
885 "@clock,"
886 "@module,"
887 "@raw-io,"
888 "@reboot,"
889 "@swap,"
890#ifdef SYS__sysctl
891 "_sysctl,"
892#endif
893#ifdef SYS_acct
894 "acct,"
895#endif
896#ifdef SYS_bpf
897 "bpf,"
898#endif
899#ifdef SYS_capset
900 "capset,"
901#endif
902#ifdef SYS_chroot
903 "chroot,"
904#endif
905#ifdef SYS_fanotify_init
906 "fanotify_init,"
907#endif
908#ifdef SYS_mount
909 "mount,"
910#endif
911#ifdef SYS_nfsservctl
912 "nfsservctl,"
913#endif
914#ifdef SYS_open_by_handle_at
915 "open_by_handle_at,"
916#endif
917#ifdef SYS_pivot_root
918 "pivot_root,"
919#endif
920#ifdef SYS_quotactl
921 "quotactl,"
922#endif
923#ifdef SYS_setdomainname
924 "setdomainname,"
925#endif
926#ifdef SYS_setfsuid
927 "setfsuid,"
928#endif
929#ifdef SYS_setfsuid32
930 "setfsuid32,"
931#endif
932#ifdef SYS_setgroups
933 "setgroups,"
934#endif
935#ifdef SYS_setgroups32
936 "setgroups32,"
937#endif
938#ifdef SYS_sethostname
939 "sethostname,"
940#endif
941#ifdef SYS_setresuid
942 "setresuid,"
943#endif
944#ifdef SYS_setresuid32
945 "setresuid32,"
946#endif
947#ifdef SYS_setreuid
948 "setreuid,"
949#endif
950#ifdef SYS_setreuid32
951 "setreuid32,"
952#endif
953#ifdef SYS_setuid
954 "setuid,"
955#endif
956#ifdef SYS_setuid32
957 "setuid32,"
958#endif
959#ifdef SYS_umount2
960 "umount2,"
961#endif
962#ifdef SYS_vhangup
963 "vhangup"
964#endif
965 },
966 { .name = "@process", .list =
967#ifdef SYS_arch_prctl
968 "arch_prctl,"
969#endif
970#ifdef SYS_capget
971 "capget,"
972#endif
973#ifdef SYS_clone
974 "clone,"
975#endif
976#ifdef SYS_execveat
977 "execveat,"
978#endif
979#ifdef SYS_fork
980 "fork,"
981#endif
982#ifdef SYS_getrusage
983 "getrusage,"
984#endif
985#ifdef SYS_kill
986 "kill,"
987#endif
988#ifdef SYS_pidfd_send_signal
989 "pidfd_send_signal,"
990#endif
991#ifdef SYS_prctl
992 "prctl,"
993#endif
994#ifdef SYS_rt_sigqueueinfo
995 "rt_sigqueueinfo,"
996#endif
997#ifdef SYS_rt_tgsigqueueinfo
998 "rt_tgsigqueueinfo,"
999#endif
1000#ifdef SYS_setns
1001 "setns,"
1002#endif
1003#ifdef SYS_swapcontext
1004 "swapcontext,"
1005#endif
1006#ifdef SYS_tgkill
1007 "tgkill,"
1008#endif
1009#ifdef SYS_times
1010 "times,"
1011#endif
1012#ifdef SYS_tkill
1013 "tkill,"
1014#endif
1015#ifdef SYS_unshare
1016 "unshare,"
1017#endif
1018#ifdef SYS_vfork
1019 "vfork,"
1020#endif
1021#ifdef SYS_wait4
1022 "wait4,"
1023#endif
1024#ifdef SYS_waitid
1025 "waitid,"
1026#endif
1027#ifdef SYS_waitpid
1028 "waitpid"
1029#endif
1030 },
1031 { .name = "@raw-io", .list =
1032#ifdef SYS_ioperm
1033 "ioperm,"
1034#endif
1035#ifdef SYS_iopl
1036 "iopl,"
1037#endif
1038#ifdef SYS_pciconfig_iobase
1039 "pciconfig_iobase,"
1040#endif
1041#ifdef SYS_pciconfig_read
1042 "pciconfig_read,"
1043#endif
1044#ifdef SYS_pciconfig_write
1045 "pciconfig_write,"
1046#endif
1047#ifdef SYS_s390_mmio_read
1048 "s390_mmio_read,"
1049#endif
1050#ifdef SYS_s390_mmio_write
1051 "s390_mmio_write"
1052#endif
1053#if !defined(SYS_ioperm) && !defined(SYS_iopl) && !defined(SYS_pciconfig_iobase) && !defined(SYS_pciconfig_read) && !defined(SYS_pciconfig_write) && !defined(SYS_s390_mmio_read) && !defined(SYS_s390_mmio_write)
1054 "__dummy_syscall__" // workaround for s390x which doesn't have any of above defined and empty syscall lists are not allowed
1055#endif
1056 },
1057 { .name = "@reboot", .list =
1058#ifdef SYS_kexec_load
1059 "kexec_load,"
1060#endif
1061#ifdef SYS_kexec_file_load
1062 "kexec_file_load,"
1063#endif
1064#ifdef SYS_reboot
1065 "reboot,"
1066#endif
1067 },
1068 { .name = "@resources", .list =
1069#ifdef SYS_ioprio_set
1070 "ioprio_set,"
1071#endif
1072#ifdef SYS_mbind
1073 "mbind,"
1074#endif
1075#ifdef SYS_migrate_pages
1076 "migrate_pages,"
1077#endif
1078#ifdef SYS_move_pages
1079 "move_pages,"
1080#endif
1081#ifdef SYS_nice
1082 "nice,"
1083#endif
1084#ifdef SYS_sched_setaffinity
1085 "sched_setaffinity,"
1086#endif
1087#ifdef SYS_sched_setattr
1088 "sched_setattr,"
1089#endif
1090#ifdef SYS_sched_setparam
1091 "sched_setparam,"
1092#endif
1093#ifdef SYS_sched_setscheduler
1094 "sched_setscheduler,"
1095#endif
1096#ifdef SYS_set_mempolicy
1097 "set_mempolicy"
1098#endif
1099 },
1100 { .name = "@setuid", .list =
1101#ifdef SYS_setgid
1102 "setgid,"
1103#endif
1104#ifdef SYS_setgid32
1105 "setgid32,"
1106#endif
1107#ifdef SYS_setgroups
1108 "setgroups,"
1109#endif
1110#ifdef SYS_setgroups32
1111 "setgroups32,"
1112#endif
1113#ifdef SYS_setregid
1114 "setregid,"
1115#endif
1116#ifdef SYS_setregid32
1117 "setregid32,"
1118#endif
1119#ifdef SYS_setresgid
1120 "setresgid,"
1121#endif
1122#ifdef SYS_setresgid32
1123 "setresgid32,"
1124#endif
1125#ifdef SYS_setresuid
1126 "setresuid,"
1127#endif
1128#ifdef SYS_setresuid32
1129 "setresuid32,"
1130#endif
1131#ifdef SYS_setreuid
1132 "setreuid,"
1133#endif
1134#ifdef SYS_setreuid32
1135 "setreuid32,"
1136#endif
1137#ifdef SYS_setuid
1138 "setuid,"
1139#endif
1140#ifdef SYS_setuid32
1141 "setuid32"
1142#endif
1143 },
1144 { .name = "@signal", .list =
1145#ifdef SYS_rt_sigaction
1146 "rt_sigaction,"
1147#endif
1148#ifdef SYS_rt_sigpending
1149 "rt_sigpending,"
1150#endif
1151#ifdef SYS_rt_sigprocmask
1152 "rt_sigprocmask,"
1153#endif
1154#ifdef SYS_rt_sigsuspend
1155 "rt_sigsuspend,"
1156#endif
1157#ifdef SYS_rt_sigtimedwait
1158 "rt_sigtimedwait,"
1159#endif
1160#ifdef SYS_sigaction
1161 "sigaction,"
1162#endif
1163#ifdef SYS_sigaltstack
1164 "sigaltstack,"
1165#endif
1166#ifdef SYS_signal
1167 "signal,"
1168#endif
1169#ifdef SYS_signalfd
1170 "signalfd,"
1171#endif
1172#ifdef SYS_signalfd4
1173 "signalfd4,"
1174#endif
1175#ifdef SYS_sigpending
1176 "sigpending,"
1177#endif
1178#ifdef SYS_sigprocmask
1179 "sigprocmask,"
1180#endif
1181#ifdef SYS_sigsuspend
1182 "sigsuspend"
1183#endif
1184 },
1185 { .name = "@swap", .list =
1186#ifdef SYS_swapon
1187 "swapon,"
1188#endif
1189#ifdef SYS_swapoff
1190 "swapoff"
1191#endif
1192 },
1193 { .name = "@sync", .list =
1194#ifdef SYS_fdatasync
1195 "fdatasync,"
1196#endif
1197#ifdef SYS_fsync
1198 "fsync,"
1199#endif
1200#ifdef SYS_msync
1201 "msync,"
1202#endif
1203#ifdef SYS_sync
1204 "sync,"
1205#endif
1206#ifdef SYS_sync_file_range
1207 "sync_file_range,"
1208#endif
1209#ifdef SYS_sync_file_range2
1210 "sync_file_range2,"
1211#endif
1212#ifdef SYS_syncfs
1213 "syncfs"
1214#endif
1215 },
1216 { .name = "@system-service", .list =
1217 "@aio,"
1218 "@basic-io,"
1219 "@chown,"
1220 "@default,"
1221 "@file-system,"
1222 "@io-event,"
1223 "@ipc,"
1224 "@keyring,"
1225 "@memlock,"
1226 "@network-io,"
1227 "@process,"
1228 "@resources,"
1229 "@setuid,"
1230 "@signal,"
1231 "@sync,"
1232 "@timer,"
1233#ifdef SYS_brk
1234 "brk,"
1235#endif
1236#ifdef SYS_capget
1237 "capget,"
1238#endif
1239#ifdef SYS_capset
1240 "capset,"
1241#endif
1242#ifdef SYS_copy_file_range
1243 "copy_file_range,"
1244#endif
1245#ifdef SYS_fadvise64
1246 "fadvise64,"
1247#endif
1248#ifdef SYS_fadvise64_64
1249 "fadvise64_64,"
1250#endif
1251#ifdef SYS_flock
1252 "flock,"
1253#endif
1254#ifdef SYS_get_mempolicy
1255 "get_mempolicy,"
1256#endif
1257#ifdef SYS_getcpu
1258 "getcpu,"
1259#endif
1260#ifdef SYS_getpriority
1261 "getpriority,"
1262#endif
1263#ifdef SYS_getrandom
1264 "getrandom,"
1265#endif
1266#ifdef SYS_ioctl
1267 "ioctl,"
1268#endif
1269#ifdef SYS_ioprio_get
1270 "ioprio_get,"
1271#endif
1272#ifdef SYS_kcmp
1273 "kcmp,"
1274#endif
1275#ifdef SYS_madvise
1276 "madvise,"
1277#endif
1278#ifdef SYS_mprotect
1279 "mprotect,"
1280#endif
1281#ifdef SYS_mremap
1282 "mremap,"
1283#endif
1284#ifdef SYS_name_to_handle_at
1285 "name_to_handle_at,"
1286#endif
1287#ifdef SYS_oldolduname
1288 "oldolduname,"
1289#endif
1290#ifdef SYS_olduname
1291 "olduname,"
1292#endif
1293#ifdef SYS_personality
1294 "personality,"
1295#endif
1296#ifdef SYS_readahead
1297 "readahead,"
1298#endif
1299#ifdef SYS_readdir
1300 "readdir,"
1301#endif
1302#ifdef SYS_remap_file_pages
1303 "remap_file_pages,"
1304#endif
1305#ifdef SYS_sched_get_priority_max
1306 "sched_get_priority_max,"
1307#endif
1308#ifdef SYS_sched_get_priority_min
1309 "sched_get_priority_min,"
1310#endif
1311#ifdef SYS_sched_getaffinity
1312 "sched_getaffinity,"
1313#endif
1314#ifdef SYS_sched_getattr
1315 "sched_getattr,"
1316#endif
1317#ifdef SYS_sched_getparam
1318 "sched_getparam,"
1319#endif
1320#ifdef SYS_sched_getscheduler
1321 "sched_getscheduler,"
1322#endif
1323#ifdef SYS_sched_rr_get_interval
1324 "sched_rr_get_interval,"
1325#endif
1326#ifdef SYS_sched_yield
1327 "sched_yield,"
1328#endif
1329#ifdef SYS_sendfile
1330 "sendfile,"
1331#endif
1332#ifdef SYS_sendfile64
1333 "sendfile64,"
1334#endif
1335#ifdef SYS_setfsgid
1336 "setfsgid,"
1337#endif
1338#ifdef SYS_setfsgid32
1339 "setfsgid32,"
1340#endif
1341#ifdef SYS_setfsuid
1342 "setfsuid,"
1343#endif
1344#ifdef SYS_setfsuid32
1345 "setfsuid32,"
1346#endif
1347#ifdef SYS_setpgid
1348 "setpgid,"
1349#endif
1350#ifdef SYS_setsid
1351 "setsid,"
1352#endif
1353#ifdef SYS_splice
1354 "splice,"
1355#endif
1356#ifdef SYS_sysinfo
1357 "sysinfo,"
1358#endif
1359#ifdef SYS_tee
1360 "tee,"
1361#endif
1362#ifdef SYS_umask
1363 "umask,"
1364#endif
1365#ifdef SYS_uname
1366 "uname,"
1367#endif
1368#ifdef SYS_userfaultfd
1369 "userfaultfd,"
1370#endif
1371#ifdef SYS_vmsplice
1372 "vmsplice"
1373#endif
1374 },
1375 { .name = "@timer", .list =
1376#ifdef SYS_alarm
1377 "alarm,"
1378#endif
1379#ifdef SYS_getitimer
1380 "getitimer,"
1381#endif
1382#ifdef SYS_setitimer
1383 "setitimer,"
1384#endif
1385#ifdef SYS_timer_create
1386 "timer_create,"
1387#endif
1388#ifdef SYS_timer_delete
1389 "timer_delete,"
1390#endif
1391#ifdef SYS_timer_getoverrun
1392 "timer_getoverrun,"
1393#endif
1394#ifdef SYS_timer_gettime
1395 "timer_gettime,"
1396#endif
1397#ifdef SYS_timer_settime
1398 "timer_settime,"
1399#endif
1400#ifdef SYS_timerfd_create
1401 "timerfd_create,"
1402#endif
1403#ifdef SYS_timerfd_gettime
1404 "timerfd_gettime,"
1405#endif
1406#ifdef SYS_timerfd_settime
1407 "timerfd_settime,"
1408#endif
1409#ifdef SYS_times
1410 "times"
1411#endif
1412 }
1413};
1414
1415// return -1 if error, or syscall number
1416static int syscall_find_name(const char *name) {
1417 int i;
1418 int elems = sizeof(syslist) / sizeof(syslist[0]);
1419 for (i = 0; i < elems; i++) {
1420 if (strcmp(name, syslist[i].name) == 0)
1421 return syslist[i].nr;
1422 }
1423
1424 return -1;
1425}
1426
1427const char *syscall_find_nr(int nr) {
1428 int i;
1429 int elems = sizeof(syslist) / sizeof(syslist[0]);
1430 for (i = 0; i < elems; i++) {
1431 if (nr == syslist[i].nr)
1432 return syslist[i].name;
1433 }
1434
1435 return "unknown";
1436}
1437
1438void syscall_print(void) {
1439 int i;
1440 int elems = sizeof(syslist) / sizeof(syslist[0]);
1441 for (i = 0; i < elems; i++) {
1442 printf("%d\t- %s\n", syslist[i].nr, syslist[i].name);
1443 }
1444 printf("\n");
1445}
1446
1447static const char *syscall_find_group(const char *name) {
1448 int i;
1449 int elems = sizeof(sysgroups) / sizeof(sysgroups[0]);
1450 for (i = 0; i < elems; i++) {
1451 if (strcmp(name, sysgroups[i].name) == 0)
1452 return sysgroups[i].list;
1453 }
1454
1455 return NULL;
1456}
1457
1458// allowed input:
1459// - syscall
1460// - syscall(error)
1461static void syscall_process_name(const char *name, int *syscall_nr, int *error_nr) {
1462 assert(name);
1463 if (strlen(name) == 0)
1464 goto error;
1465 *error_nr = -1;
1466
1467 // syntax check
1468 char *str = strdup(name);
1469 if (!str)
1470 errExit("strdup");
1471
1472 char *syscall_name = str;
1473 char *error_name = strchr(str, ':');
1474 if (error_name) {
1475 *error_name = '\0';
1476 error_name++;
1477 }
1478 if (strlen(syscall_name) == 0) {
1479 free(str);
1480 goto error;
1481 }
1482
1483 if (*syscall_name == '$')
1484 *syscall_nr = strtol(syscall_name + 1, NULL, 0);
1485 else
1486 *syscall_nr = syscall_find_name(syscall_name);
1487 if (error_name) {
1488 *error_nr = errno_find_name(error_name);
1489 if (*error_nr == -1)
1490 *syscall_nr = -1;
1491 }
1492
1493 free(str);
1494 return;
1495
1496error:
1497 fprintf(stderr, "Error fseccomp: invalid syscall list entry %s\n", name);
1498 exit(1);
1499}
1500
1501// return 1 if error, 0 if OK
1502int syscall_check_list(const char *slist, void (*callback)(int fd, int syscall, int arg, void *ptrarg), int fd, int arg, void *ptrarg) {
1503 // don't allow empty lists
1504 if (slist == NULL || *slist == '\0') {
1505 fprintf(stderr, "Error fseccomp: empty syscall lists are not allowed\n");
1506 exit(1);
1507 }
1508
1509 // work on a copy of the string
1510 char *str = strdup(slist);
1511 if (!str)
1512 errExit("strdup");
1513
1514 char *saveptr;
1515 char *ptr = strtok_r(str, ",", &saveptr);
1516 if (ptr == NULL) {
1517 fprintf(stderr, "Error fseccomp: empty syscall lists are not allowed\n");
1518 exit(1);
1519 }
1520
1521 while (ptr) {
1522 int syscall_nr;
1523 int error_nr;
1524 if (*ptr == '@') {
1525 const char *new_list = syscall_find_group(ptr);
1526 if (!new_list) {
1527 fprintf(stderr, "Error fseccomp: unknown syscall group %s\n", ptr);
1528 exit(1);
1529 }
1530 syscall_check_list(new_list, callback, fd, arg, ptrarg);
1531 }
1532 else {
1533 bool negate = false;
1534 if (*ptr == '!') {
1535 negate = true;
1536 ptr++;
1537 }
1538 syscall_process_name(ptr, &syscall_nr, &error_nr);
1539 if (syscall_nr == -1) {;}
1540 else if (callback != NULL) {
1541 if (negate) {
1542 syscall_nr = -syscall_nr;
1543 }
1544 if (error_nr != -1 && fd != 0) {
1545 filter_add_errno(fd, syscall_nr, error_nr, ptrarg);
1546 }
1547 else if (error_nr != -1 && fd == 0) {
1548 callback(fd, syscall_nr, error_nr, ptrarg);
1549 }
1550 else {
1551 callback(fd, syscall_nr, arg, ptrarg);
1552 }
1553 }
1554 }
1555 ptr = strtok_r(NULL, ",", &saveptr);
1556 }
1557
1558 free(str);
1559 return 0;
1560}
1561
1562static void find_syscall(int fd, int syscall, int arg, void *ptrarg) {
1563 (void)fd;
1564 (void) arg;
1565 SyscallCheckList *ptr = ptrarg;
1566 if (abs(syscall) == ptr->syscall)
1567 ptr->found = true;
1568}
1569
1570// go through list2 and find matches for problem syscall
1571static void syscall_in_list(int fd, int syscall, int arg, void *ptrarg) {
1572 (void) fd;
1573 (void)arg;
1574 SyscallCheckList *ptr = ptrarg;
1575 SyscallCheckList sl;
1576 sl.found = false;
1577 sl.syscall = syscall;
1578 syscall_check_list(ptr->slist, find_syscall, fd, 0, &sl);
1579 // if found in the problem list, add to post-exec list
1580 if (sl.found) {
1581 if (ptr->postlist) {
1582 if (asprintf(&ptr->postlist, "%s,%s", ptr->postlist, syscall_find_nr(syscall)) == -1)
1583 errExit("asprintf");
1584 }
1585 else
1586 ptr->postlist = strdup(syscall_find_nr(syscall));
1587 }
1588 else { // no problem, add to pre-exec list
1589 // build syscall:error_no
1590 char *newcall = NULL;
1591 if (arg != 0) {
1592 if (asprintf(&newcall, "%s:%s", syscall_find_nr(syscall), errno_find_nr(arg)) == -1)
1593 errExit("asprintf");
1594 }
1595 else {
1596 newcall = strdup(syscall_find_nr(syscall));
1597 if (!newcall)
1598 errExit("strdup");
1599 }
1600
1601 if (ptr->prelist) {
1602 if (asprintf(&ptr->prelist, "%s,%s", ptr->prelist, newcall) == -1)
1603 errExit("asprintf");
1604 free(newcall);
1605 }
1606 else
1607 ptr->prelist = newcall;
1608 }
1609}
1610
1611// go through list and find matches for syscalls in list @default-keep
1612void syscalls_in_list(const char *list, const char *slist, int fd, char **prelist, char **postlist) {
1613 (void) fd;
1614 SyscallCheckList sl;
1615 // these syscalls are used by firejail after the seccomp filter is initialized
1616 sl.slist = slist;
1617 sl.prelist = NULL;
1618 sl.postlist = NULL;
1619 syscall_check_list(list, syscall_in_list, 0, 0, &sl);
1620 if (!arg_quiet) {
1621 printf("Seccomp list in: %s,", list);
1622 if (sl.slist)
1623 printf(" check list: %s,", sl.slist);
1624 if (sl.prelist)
1625 printf(" prelist: %s,", sl.prelist);
1626 if (sl.postlist)
1627 printf(" postlist: %s", sl.postlist);
1628 printf("\n");
1629 }
1630 *prelist = sl.prelist;
1631 *postlist = sl.postlist;
1632}