diff options
Diffstat (limited to 'src/fseccomp')
-rw-r--r-- | src/fseccomp/fseccomp.h | 15 | ||||
-rw-r--r-- | src/fseccomp/main.c | 30 | ||||
-rw-r--r-- | src/fseccomp/seccomp.c | 118 | ||||
-rw-r--r-- | src/fseccomp/seccomp_file.c | 9 | ||||
-rw-r--r-- | src/fseccomp/syscall.c | 64 |
5 files changed, 183 insertions, 53 deletions
diff --git a/src/fseccomp/fseccomp.h b/src/fseccomp/fseccomp.h index 0db670380..144b612ae 100644 --- a/src/fseccomp/fseccomp.h +++ b/src/fseccomp/fseccomp.h | |||
@@ -30,8 +30,9 @@ extern int arg_quiet; | |||
30 | 30 | ||
31 | // syscall.c | 31 | // syscall.c |
32 | void syscall_print(void); | 32 | void syscall_print(void); |
33 | int syscall_check_list(const char *slist, void (*callback)(int fd, int syscall, int arg), int fd, int arg); | 33 | int syscall_check_list(const char *slist, void (*callback)(int fd, int syscall, int arg, void *ptrarg), int fd, int arg, void *ptrarg); |
34 | const char *syscall_find_nr(int nr); | 34 | const char *syscall_find_nr(int nr); |
35 | void syscalls_in_list(const char *list, const char *slist, int fd, char **prelist, char **postlist); | ||
35 | 36 | ||
36 | // errno.c | 37 | // errno.c |
37 | void errno_print(void); | 38 | void errno_print(void); |
@@ -49,9 +50,9 @@ void seccomp_secondary_32(const char *fname); | |||
49 | // seccomp_file.c | 50 | // seccomp_file.c |
50 | void write_to_file(int fd, const void *data, int size); | 51 | void write_to_file(int fd, const void *data, int size); |
51 | void filter_init(int fd); | 52 | void filter_init(int fd); |
52 | void filter_add_whitelist(int fd, int syscall, int arg); | 53 | void filter_add_whitelist(int fd, int syscall, int arg, void *ptrarg); |
53 | void filter_add_blacklist(int fd, int syscall, int arg); | 54 | void filter_add_blacklist(int fd, int syscall, int arg, void *ptrarg); |
54 | void filter_add_errno(int fd, int syscall, int arg); | 55 | void filter_add_errno(int fd, int syscall, int arg, void *ptrarg); |
55 | void filter_end_blacklist(int fd); | 56 | void filter_end_blacklist(int fd); |
56 | void filter_end_whitelist(int fd); | 57 | void filter_end_whitelist(int fd); |
57 | 58 | ||
@@ -59,11 +60,11 @@ void filter_end_whitelist(int fd); | |||
59 | // default list | 60 | // default list |
60 | void seccomp_default(const char *fname, int allow_debuggers); | 61 | void seccomp_default(const char *fname, int allow_debuggers); |
61 | // drop list | 62 | // drop list |
62 | void seccomp_drop(const char *fname, char *list, int allow_debuggers); | 63 | void seccomp_drop(const char *fname1, const char *fname2, char *list, int allow_debuggers); |
63 | // default+drop list | 64 | // default+drop list |
64 | void seccomp_default_drop(const char *fname, char *list, int allow_debuggers); | 65 | void seccomp_default_drop(const char *fname1, const char *fname2, char *list, int allow_debuggers); |
65 | // whitelisted filter | 66 | // whitelisted filter |
66 | void seccomp_keep(const char *fname, char *list); | 67 | void seccomp_keep(const char *fname1, const char *fname2, char *list); |
67 | // block writable and executable memory | 68 | // block writable and executable memory |
68 | void memory_deny_write_execute(const char *fname); | 69 | void memory_deny_write_execute(const char *fname); |
69 | 70 | ||
diff --git a/src/fseccomp/main.c b/src/fseccomp/main.c index 3d95d5bb2..3bf7de0fa 100644 --- a/src/fseccomp/main.c +++ b/src/fseccomp/main.c | |||
@@ -30,11 +30,11 @@ static void usage(void) { | |||
30 | printf("\tfseccomp secondary 32 file\n"); | 30 | printf("\tfseccomp secondary 32 file\n"); |
31 | printf("\tfseccomp default file\n"); | 31 | printf("\tfseccomp default file\n"); |
32 | printf("\tfseccomp default file allow-debuggers\n"); | 32 | printf("\tfseccomp default file allow-debuggers\n"); |
33 | printf("\tfseccomp drop file list\n"); | 33 | printf("\tfseccomp drop file1 file2 list\n"); |
34 | printf("\tfseccomp drop file list allow-debuggers\n"); | 34 | printf("\tfseccomp drop file1 file2 list allow-debuggers\n"); |
35 | printf("\tfseccomp default drop file list\n"); | 35 | printf("\tfseccomp default drop file1 file2 list\n"); |
36 | printf("\tfseccomp default drop file list allow-debuggers\n"); | 36 | printf("\tfseccomp default drop file1 file2 list allow-debuggers\n"); |
37 | printf("\tfseccomp keep file list\n"); | 37 | printf("\tfseccomp keep file1 file2 list\n"); |
38 | printf("\tfseccomp memory-deny-write-execute file\n"); | 38 | printf("\tfseccomp memory-deny-write-execute file\n"); |
39 | printf("\tfseccomp print file\n"); | 39 | printf("\tfseccomp print file\n"); |
40 | } | 40 | } |
@@ -78,16 +78,16 @@ printf("\n"); | |||
78 | seccomp_default(argv[2], 0); | 78 | seccomp_default(argv[2], 0); |
79 | else if (argc == 4 && strcmp(argv[1], "default") == 0 && strcmp(argv[3], "allow-debuggers") == 0) | 79 | else if (argc == 4 && strcmp(argv[1], "default") == 0 && strcmp(argv[3], "allow-debuggers") == 0) |
80 | seccomp_default(argv[2], 1); | 80 | seccomp_default(argv[2], 1); |
81 | else if (argc == 4 && strcmp(argv[1], "drop") == 0) | 81 | else if (argc == 5 && strcmp(argv[1], "drop") == 0) |
82 | seccomp_drop(argv[2], argv[3], 0); | 82 | seccomp_drop(argv[2], argv[3], argv[4], 0); |
83 | else if (argc == 5 && strcmp(argv[1], "drop") == 0 && strcmp(argv[4], "allow-debuggers") == 0) | 83 | else if (argc == 6 && strcmp(argv[1], "drop") == 0 && strcmp(argv[5], "allow-debuggers") == 0) |
84 | seccomp_drop(argv[2], argv[3], 1); | 84 | seccomp_drop(argv[2], argv[3], argv[4], 1); |
85 | else if (argc == 5 && strcmp(argv[1], "default") == 0 && strcmp(argv[2], "drop") == 0) | 85 | else if (argc == 6 && strcmp(argv[1], "default") == 0 && strcmp(argv[2], "drop") == 0) |
86 | seccomp_default_drop(argv[3], argv[4], 0); | 86 | seccomp_default_drop(argv[3], argv[4], argv[5], 0); |
87 | else if (argc == 6 && strcmp(argv[1], "default") == 0 && strcmp(argv[2], "drop") == 0 && strcmp(argv[5], "allow-debuggers") == 0) | 87 | 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], 1); | 88 | seccomp_default_drop(argv[3], argv[4], argv[5], 1); |
89 | else if (argc == 4 && strcmp(argv[1], "keep") == 0) | 89 | else if (argc == 5 && strcmp(argv[1], "keep") == 0) |
90 | seccomp_keep(argv[2], argv[3]); | 90 | seccomp_keep(argv[2], argv[3], argv[4]); |
91 | else if (argc == 3 && strcmp(argv[1], "memory-deny-write-execute") == 0) | 91 | else if (argc == 3 && strcmp(argv[1], "memory-deny-write-execute") == 0) |
92 | memory_deny_write_execute(argv[2]); | 92 | memory_deny_write_execute(argv[2]); |
93 | else if (argc == 3 && strcmp(argv[1], "print") == 0) | 93 | else if (argc == 3 && strcmp(argv[1], "print") == 0) |
diff --git a/src/fseccomp/seccomp.c b/src/fseccomp/seccomp.c index a3db46aad..577f3fdc9 100644 --- a/src/fseccomp/seccomp.c +++ b/src/fseccomp/seccomp.c | |||
@@ -27,9 +27,9 @@ | |||
27 | static void add_default_list(int fd, int allow_debuggers) { | 27 | static void add_default_list(int fd, int allow_debuggers) { |
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); | 30 | r = syscall_check_list("@default-nodebuggers", filter_add_blacklist, fd, 0, NULL); |
31 | else | 31 | else |
32 | r = syscall_check_list("@default", filter_add_blacklist, fd, 0); | 32 | r = syscall_check_list("@default", filter_add_blacklist, fd, 0, NULL); |
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 |
@@ -56,7 +56,7 @@ void seccomp_default(const char *fname, int allow_debuggers) { | |||
56 | exit(1); | 56 | exit(1); |
57 | } | 57 | } |
58 | 58 | ||
59 | // build filter | 59 | // build filter (no post-exec filter needed because default list is fine for us) |
60 | filter_init(fd); | 60 | filter_init(fd); |
61 | add_default_list(fd, allow_debuggers); | 61 | add_default_list(fd, allow_debuggers); |
62 | filter_end_blacklist(fd); | 62 | filter_end_blacklist(fd); |
@@ -66,44 +66,94 @@ void seccomp_default(const char *fname, int allow_debuggers) { | |||
66 | } | 66 | } |
67 | 67 | ||
68 | // drop list | 68 | // drop list |
69 | void seccomp_drop(const char *fname, char *list, int allow_debuggers) { | 69 | void seccomp_drop(const char *fname1, const char *fname2, char *list, int allow_debuggers) { |
70 | assert(fname); | 70 | assert(fname1); |
71 | assert(fname2); | ||
71 | (void) allow_debuggers; // todo: to implemnet it | 72 | (void) allow_debuggers; // todo: to implemnet it |
72 | 73 | ||
73 | // open file | 74 | // open file for pre-exec filter |
74 | int fd = open(fname, O_CREAT|O_WRONLY|O_TRUNC, S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH); | 75 | int fd = open(fname1, O_CREAT|O_WRONLY|O_TRUNC, S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH); |
75 | if (fd < 0) { | 76 | if (fd < 0) { |
76 | fprintf(stderr, "Error fseccomp: cannot open %s file\n", fname); | 77 | fprintf(stderr, "Error fseccomp: cannot open %s file\n", fname1); |
77 | exit(1); | 78 | exit(1); |
78 | } | 79 | } |
79 | 80 | ||
80 | // build filter | 81 | // build pre-exec filter: don't blacklist any syscalls in @default-keep |
82 | filter_init(fd); | ||
83 | char *prelist, *postlist; | ||
84 | syscalls_in_list(list, "@default-keep", fd, &prelist, &postlist); | ||
85 | if (prelist) | ||
86 | if (syscall_check_list(prelist, filter_add_blacklist, fd, 0, NULL)) { | ||
87 | fprintf(stderr, "Error fseccomp: cannot build seccomp filter\n"); | ||
88 | exit(1); | ||
89 | } | ||
90 | filter_end_whitelist(fd); | ||
91 | // close file | ||
92 | close(fd); | ||
93 | |||
94 | if (!postlist) | ||
95 | return; | ||
96 | |||
97 | // open file for post-exec filter | ||
98 | fd = open(fname2, O_CREAT|O_WRONLY|O_TRUNC, S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH); | ||
99 | if (fd < 0) { | ||
100 | fprintf(stderr, "Error fseccomp: cannot open %s file\n", fname2); | ||
101 | exit(1); | ||
102 | } | ||
103 | |||
104 | // build post-exec filter: blacklist remaining syscalls | ||
81 | filter_init(fd); | 105 | filter_init(fd); |
82 | if (syscall_check_list(list, filter_add_blacklist, fd, 0)) { | 106 | if (syscall_check_list(postlist, filter_add_blacklist, fd, 0, NULL)) { |
83 | fprintf(stderr, "Error fseccomp: cannot build seccomp filter\n"); | 107 | fprintf(stderr, "Error fseccomp: cannot build seccomp filter\n"); |
84 | exit(1); | 108 | exit(1); |
85 | } | 109 | } |
86 | filter_end_blacklist(fd); | 110 | filter_end_whitelist(fd); |
87 | 111 | ||
88 | // close file | 112 | // close file |
89 | close(fd); | 113 | close(fd); |
90 | } | 114 | } |
91 | 115 | ||
92 | // default+drop | 116 | // default+drop |
93 | void seccomp_default_drop(const char *fname, char *list, int allow_debuggers) { | 117 | void seccomp_default_drop(const char *fname1, const char *fname2, char *list, int allow_debuggers) { |
94 | assert(fname); | 118 | assert(fname1); |
119 | assert(fname2); | ||
95 | 120 | ||
96 | // open file | 121 | // open file |
97 | int fd = open(fname, O_CREAT|O_WRONLY|O_TRUNC, S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH); | 122 | int fd = open(fname1, O_CREAT|O_WRONLY|O_TRUNC, S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH); |
98 | if (fd < 0) { | 123 | if (fd < 0) { |
99 | fprintf(stderr, "Error fseccomp: cannot open %s file\n", fname); | 124 | fprintf(stderr, "Error fseccomp: cannot open %s file\n", fname1); |
100 | exit(1); | 125 | exit(1); |
101 | } | 126 | } |
102 | 127 | ||
103 | // build filter | 128 | // build pre-exec filter: blacklist @default, don't blacklist |
129 | // any listed syscalls in @default-keep | ||
104 | filter_init(fd); | 130 | filter_init(fd); |
105 | add_default_list(fd, allow_debuggers); | 131 | add_default_list(fd, allow_debuggers); |
106 | if (syscall_check_list(list, filter_add_blacklist, fd, 0)) { | 132 | char *prelist, *postlist; |
133 | syscalls_in_list(list, "@default-keep", fd, &prelist, &postlist); | ||
134 | if (prelist) | ||
135 | if (syscall_check_list(prelist, filter_add_blacklist, fd, 0, NULL)) { | ||
136 | fprintf(stderr, "Error fseccomp: cannot build seccomp filter\n"); | ||
137 | exit(1); | ||
138 | } | ||
139 | filter_end_blacklist(fd); | ||
140 | |||
141 | // close file | ||
142 | close(fd); | ||
143 | |||
144 | if (!postlist) | ||
145 | return; | ||
146 | |||
147 | // open file for post-exec filter | ||
148 | fd = open(fname2, O_CREAT|O_WRONLY|O_TRUNC, S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH); | ||
149 | if (fd < 0) { | ||
150 | fprintf(stderr, "Error fseccomp: cannot open %s file\n", fname2); | ||
151 | exit(1); | ||
152 | } | ||
153 | |||
154 | // build post-exec filter: blacklist remaining syscalls | ||
155 | filter_init(fd); | ||
156 | if (syscall_check_list(postlist, filter_add_blacklist, fd, 0, NULL)) { | ||
107 | fprintf(stderr, "Error fseccomp: cannot build seccomp filter\n"); | 157 | fprintf(stderr, "Error fseccomp: cannot build seccomp filter\n"); |
108 | exit(1); | 158 | exit(1); |
109 | } | 159 | } |
@@ -113,22 +163,42 @@ void seccomp_default_drop(const char *fname, char *list, int allow_debuggers) { | |||
113 | close(fd); | 163 | close(fd); |
114 | } | 164 | } |
115 | 165 | ||
116 | void seccomp_keep(const char *fname, char *list) { | 166 | void seccomp_keep(const char *fname1, const char *fname2, char *list) { |
117 | // open file | 167 | // open file for pre-exec filter |
118 | int fd = open(fname, O_CREAT|O_WRONLY|O_TRUNC, S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH); | 168 | int fd = open(fname1, O_CREAT|O_WRONLY|O_TRUNC, S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH); |
119 | if (fd < 0) { | 169 | if (fd < 0) { |
120 | fprintf(stderr, "Error fseccomp: cannot open %s file\n", fname); | 170 | fprintf(stderr, "Error fseccomp: cannot open %s file\n", fname1); |
121 | exit(1); | 171 | exit(1); |
122 | } | 172 | } |
123 | 173 | ||
124 | // build filter | 174 | // build pre-exec filter: whitelist also @default-keep |
125 | filter_init(fd); | 175 | filter_init(fd); |
126 | // these syscalls are used by firejail after the seccomp filter is initialized | 176 | // these syscalls are used by firejail after the seccomp filter is initialized |
127 | int r; | 177 | int r; |
128 | r = syscall_check_list("@default-keep", filter_add_whitelist, fd, 0); | 178 | r = syscall_check_list("@default-keep", filter_add_whitelist, fd, 0, NULL); |
129 | assert(r == 0); | 179 | assert(r == 0); |
130 | 180 | ||
131 | if (syscall_check_list(list, filter_add_whitelist, fd, 0)) { | 181 | if (syscall_check_list(list, filter_add_whitelist, fd, 0, NULL)) { |
182 | fprintf(stderr, "Error fseccomp: cannot build seccomp filter\n"); | ||
183 | exit(1); | ||
184 | } | ||
185 | |||
186 | filter_end_whitelist(fd); | ||
187 | |||
188 | // close file | ||
189 | close(fd); | ||
190 | |||
191 | // open file for post-exec filter | ||
192 | fd = open(fname2, O_CREAT|O_WRONLY|O_TRUNC, S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH); | ||
193 | if (fd < 0) { | ||
194 | fprintf(stderr, "Error fseccomp: cannot open %s file\n", fname2); | ||
195 | exit(1); | ||
196 | } | ||
197 | |||
198 | // build post-exec filter: whitelist without @default-keep | ||
199 | filter_init(fd); | ||
200 | |||
201 | if (syscall_check_list(list, filter_add_whitelist, fd, 0, NULL)) { | ||
132 | fprintf(stderr, "Error fseccomp: cannot build seccomp filter\n"); | 202 | fprintf(stderr, "Error fseccomp: cannot build seccomp filter\n"); |
133 | exit(1); | 203 | exit(1); |
134 | } | 204 | } |
diff --git a/src/fseccomp/seccomp_file.c b/src/fseccomp/seccomp_file.c index 16ffd5302..2d5ee115d 100644 --- a/src/fseccomp/seccomp_file.c +++ b/src/fseccomp/seccomp_file.c | |||
@@ -60,8 +60,9 @@ void filter_init(int fd) { | |||
60 | write_to_file(fd, filter, sizeof(filter)); | 60 | write_to_file(fd, filter, sizeof(filter)); |
61 | } | 61 | } |
62 | 62 | ||
63 | void filter_add_whitelist(int fd, int syscall, int arg) { | 63 | void filter_add_whitelist(int fd, int syscall, int arg, void *ptrarg) { |
64 | (void) arg; | 64 | (void) arg; |
65 | (void) ptrarg; | ||
65 | 66 | ||
66 | struct sock_filter filter[] = { | 67 | struct sock_filter filter[] = { |
67 | WHITELIST(syscall) | 68 | WHITELIST(syscall) |
@@ -69,8 +70,9 @@ void filter_add_whitelist(int fd, int syscall, int arg) { | |||
69 | write_to_file(fd, filter, sizeof(filter)); | 70 | write_to_file(fd, filter, sizeof(filter)); |
70 | } | 71 | } |
71 | 72 | ||
72 | void filter_add_blacklist(int fd, int syscall, int arg) { | 73 | void filter_add_blacklist(int fd, int syscall, int arg, void *ptrarg) { |
73 | (void) arg; | 74 | (void) arg; |
75 | (void) ptrarg; | ||
74 | 76 | ||
75 | struct sock_filter filter[] = { | 77 | struct sock_filter filter[] = { |
76 | BLACKLIST(syscall) | 78 | BLACKLIST(syscall) |
@@ -78,7 +80,8 @@ void filter_add_blacklist(int fd, int syscall, int arg) { | |||
78 | write_to_file(fd, filter, sizeof(filter)); | 80 | write_to_file(fd, filter, sizeof(filter)); |
79 | } | 81 | } |
80 | 82 | ||
81 | void filter_add_errno(int fd, int syscall, int arg) { | 83 | void filter_add_errno(int fd, int syscall, int arg, void *ptrarg) { |
84 | (void) ptrarg; | ||
82 | struct sock_filter filter[] = { | 85 | struct sock_filter filter[] = { |
83 | BLACKLIST_ERRNO(syscall, arg) | 86 | BLACKLIST_ERRNO(syscall, arg) |
84 | }; | 87 | }; |
diff --git a/src/fseccomp/syscall.c b/src/fseccomp/syscall.c index 5893a2ea8..b9e6d995b 100644 --- a/src/fseccomp/syscall.c +++ b/src/fseccomp/syscall.c | |||
@@ -17,7 +17,9 @@ | |||
17 | * with this program; if not, write to the Free Software Foundation, Inc., | 17 | * with this program; if not, write to the Free Software Foundation, Inc., |
18 | * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. | 18 | * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. |
19 | */ | 19 | */ |
20 | #define _GNU_SOURCE | ||
20 | #include "fseccomp.h" | 21 | #include "fseccomp.h" |
22 | #include <stdio.h> | ||
21 | #include <sys/syscall.h> | 23 | #include <sys/syscall.h> |
22 | 24 | ||
23 | typedef struct { | 25 | typedef struct { |
@@ -30,6 +32,13 @@ typedef struct { | |||
30 | const char * const list; | 32 | const char * const list; |
31 | } SyscallGroupList; | 33 | } SyscallGroupList; |
32 | 34 | ||
35 | typedef struct { | ||
36 | const char *slist; | ||
37 | char *prelist, *postlist; | ||
38 | bool found; | ||
39 | int syscall; | ||
40 | } SyscallCheckList; | ||
41 | |||
33 | static const SyscallEntry syslist[] = { | 42 | static const SyscallEntry syslist[] = { |
34 | // | 43 | // |
35 | // code generated using tools/extract-syscall | 44 | // code generated using tools/extract-syscall |
@@ -174,6 +183,7 @@ static const SyscallGroupList sysgroups[] = { | |||
174 | }, | 183 | }, |
175 | { .name = "@default-keep", .list = | 184 | { .name = "@default-keep", .list = |
176 | "dup," | 185 | "dup," |
186 | "execve," | ||
177 | "prctl," | 187 | "prctl," |
178 | "setgid," | 188 | "setgid," |
179 | "setgroups," | 189 | "setgroups," |
@@ -449,7 +459,7 @@ error: | |||
449 | } | 459 | } |
450 | 460 | ||
451 | // return 1 if error, 0 if OK | 461 | // return 1 if error, 0 if OK |
452 | int syscall_check_list(const char *slist, void (*callback)(int fd, int syscall, int arg), int fd, int arg) { | 462 | int syscall_check_list(const char *slist, void (*callback)(int fd, int syscall, int arg, void *ptrarg), int fd, int arg, void *ptrarg) { |
453 | // don't allow empty lists | 463 | // don't allow empty lists |
454 | if (slist == NULL || *slist == '\0') { | 464 | if (slist == NULL || *slist == '\0') { |
455 | fprintf(stderr, "Error fseccomp: empty syscall lists are not allowed\n"); | 465 | fprintf(stderr, "Error fseccomp: empty syscall lists are not allowed\n"); |
@@ -477,7 +487,7 @@ int syscall_check_list(const char *slist, void (*callback)(int fd, int syscall, | |||
477 | fprintf(stderr, "Error fseccomp: unknown syscall group %s\n", ptr); | 487 | fprintf(stderr, "Error fseccomp: unknown syscall group %s\n", ptr); |
478 | exit(1); | 488 | exit(1); |
479 | } | 489 | } |
480 | syscall_check_list(new_list, callback, fd, arg); | 490 | syscall_check_list(new_list, callback, fd, arg, ptrarg); |
481 | } | 491 | } |
482 | else { | 492 | else { |
483 | syscall_process_name(ptr, &syscall_nr, &error_nr); | 493 | syscall_process_name(ptr, &syscall_nr, &error_nr); |
@@ -487,9 +497,9 @@ int syscall_check_list(const char *slist, void (*callback)(int fd, int syscall, | |||
487 | } | 497 | } |
488 | else if (callback != NULL) { | 498 | else if (callback != NULL) { |
489 | if (error_nr != -1) | 499 | if (error_nr != -1) |
490 | filter_add_errno(fd, syscall_nr, error_nr); | 500 | filter_add_errno(fd, syscall_nr, error_nr, ptrarg); |
491 | else | 501 | else |
492 | callback(fd, syscall_nr, arg); | 502 | callback(fd, syscall_nr, arg, ptrarg); |
493 | } | 503 | } |
494 | } | 504 | } |
495 | ptr = strtok_r(NULL, ",", &saveptr); | 505 | ptr = strtok_r(NULL, ",", &saveptr); |
@@ -498,3 +508,49 @@ int syscall_check_list(const char *slist, void (*callback)(int fd, int syscall, | |||
498 | free(str); | 508 | free(str); |
499 | return 0; | 509 | return 0; |
500 | } | 510 | } |
511 | |||
512 | static void find_syscall(int fd, int syscall, int arg, void *ptrarg) { | ||
513 | (void)fd; | ||
514 | SyscallCheckList *ptr = ptrarg; | ||
515 | if (syscall == ptr->syscall) | ||
516 | ptr->found = true; | ||
517 | } | ||
518 | |||
519 | // go through list2 and find matches for problem syscall | ||
520 | static void syscall_in_list(int fd, int syscall, int arg, void *ptrarg) { | ||
521 | (void)arg; | ||
522 | SyscallCheckList *ptr = ptrarg; | ||
523 | SyscallCheckList sl; | ||
524 | sl.found = false; | ||
525 | sl.syscall = syscall; | ||
526 | syscall_check_list(ptr->slist, find_syscall, fd, 0, &sl); | ||
527 | // if found in the problem list, add to post-exec list | ||
528 | if (sl.found) | ||
529 | if (ptr->postlist) { | ||
530 | if (asprintf(&ptr->postlist, "%s,%s", ptr->postlist, syscall_find_nr(syscall)) == -1) | ||
531 | errExit("asprintf"); | ||
532 | } | ||
533 | else | ||
534 | ptr->postlist = strdup(syscall_find_nr(syscall)); | ||
535 | else // no problem, add to pre-exec list | ||
536 | if (ptr->prelist) { | ||
537 | if (asprintf(&ptr->prelist, "%s,%s", ptr->prelist, syscall_find_nr(syscall)) == -1) | ||
538 | errExit("asprintf"); | ||
539 | } | ||
540 | else | ||
541 | ptr->prelist = strdup(syscall_find_nr(syscall)); | ||
542 | } | ||
543 | |||
544 | // go through list and find matches for syscalls in list @default-keep | ||
545 | void syscalls_in_list(const char *list, const char *slist, int fd, char **prelist, char **postlist) { | ||
546 | SyscallCheckList sl; | ||
547 | // these syscalls are used by firejail after the seccomp filter is initialized | ||
548 | sl.slist = slist; | ||
549 | sl.prelist = NULL; | ||
550 | sl.postlist = NULL; | ||
551 | syscall_check_list(list, syscall_in_list, 0, 0, &sl); | ||
552 | if (!arg_quiet) | ||
553 | printf("list in: %s, check list: %s prelist: %s, postlist: %s\n", list, sl.slist, sl.prelist, sl.postlist); | ||
554 | *prelist = sl.prelist; | ||
555 | *postlist = sl.postlist; | ||
556 | } | ||