summaryrefslogtreecommitdiffstats
path: root/src/fseccomp
diff options
context:
space:
mode:
authorLibravatar Topi Miettinen <toiwoton@gmail.com>2019-08-25 18:37:05 +0300
committerLibravatar Topi Miettinen <toiwoton@gmail.com>2019-08-25 18:37:05 +0300
commit39f9b1a2229f8624f92bdcf823ef755c15e28de2 (patch)
treec15cdcdd4abbccfdfbed58764de45827ff2e503c /src/fseccomp
parentMerge pull request #2921 from rusty-snake/allow-common-devel.inc (diff)
downloadfirejail-39f9b1a2229f8624f92bdcf823ef755c15e28de2.tar.gz
firejail-39f9b1a2229f8624f92bdcf823ef755c15e28de2.tar.zst
firejail-39f9b1a2229f8624f92bdcf823ef755c15e28de2.zip
Allow exceptions to seccomp lists
Prefix ! can be used to make exceptions to system call blacklists and whitelists used by seccomp, seccomp.drop and seccomp.keep. Closes #1366
Diffstat (limited to 'src/fseccomp')
-rw-r--r--src/fseccomp/fseccomp.h2
-rw-r--r--src/fseccomp/seccomp.c12
-rw-r--r--src/fseccomp/seccomp_file.c48
-rw-r--r--src/fseccomp/syscall.c10
4 files changed, 63 insertions, 9 deletions
diff --git a/src/fseccomp/fseccomp.h b/src/fseccomp/fseccomp.h
index 593963e76..e1579d098 100644
--- a/src/fseccomp/fseccomp.h
+++ b/src/fseccomp/fseccomp.h
@@ -52,7 +52,9 @@ void seccomp_secondary_block(const char *fname);
52void write_to_file(int fd, const void *data, int size); 52void write_to_file(int fd, const void *data, int size);
53void filter_init(int fd); 53void filter_init(int fd);
54void filter_add_whitelist(int fd, int syscall, int arg, void *ptrarg); 54void filter_add_whitelist(int fd, int syscall, int arg, void *ptrarg);
55void filter_add_whitelist_for_excluded(int fd, int syscall, int arg, void *ptrarg);
55void filter_add_blacklist(int fd, int syscall, int arg, void *ptrarg); 56void filter_add_blacklist(int fd, int syscall, int arg, void *ptrarg);
57void filter_add_blacklist_for_excluded(int fd, int syscall, int arg, void *ptrarg);
56void filter_add_errno(int fd, int syscall, int arg, void *ptrarg); 58void filter_add_errno(int fd, int syscall, int arg, void *ptrarg);
57void filter_end_blacklist(int fd); 59void filter_end_blacklist(int fd);
58void filter_end_whitelist(int fd); 60void filter_end_whitelist(int fd);
diff --git a/src/fseccomp/seccomp.c b/src/fseccomp/seccomp.c
index 2a719725e..95c20d388 100644
--- a/src/fseccomp/seccomp.c
+++ b/src/fseccomp/seccomp.c
@@ -80,6 +80,10 @@ void seccomp_drop(const char *fname1, const char *fname2, char *list, int allow_
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);
83
84 // allow exceptions in form of !syscall
85 syscall_check_list(list, filter_add_whitelist_for_excluded, fd, 0, NULL);
86
83 char *prelist, *postlist; 87 char *prelist, *postlist;
84 syscalls_in_list(list, "@default-keep", fd, &prelist, &postlist); 88 syscalls_in_list(list, "@default-keep", fd, &prelist, &postlist);
85 if (prelist) 89 if (prelist)
@@ -128,6 +132,10 @@ void seccomp_default_drop(const char *fname1, const char *fname2, char *list, in
128 // build pre-exec filter: blacklist @default, don't blacklist 132 // build pre-exec filter: blacklist @default, don't blacklist
129 // any listed syscalls in @default-keep 133 // any listed syscalls in @default-keep
130 filter_init(fd); 134 filter_init(fd);
135
136 // allow exceptions in form of !syscall
137 syscall_check_list(list, filter_add_whitelist_for_excluded, fd, 0, NULL);
138
131 add_default_list(fd, allow_debuggers); 139 add_default_list(fd, allow_debuggers);
132 char *prelist, *postlist; 140 char *prelist, *postlist;
133 syscalls_in_list(list, "@default-keep", fd, &prelist, &postlist); 141 syscalls_in_list(list, "@default-keep", fd, &prelist, &postlist);
@@ -175,6 +183,10 @@ void seccomp_keep(const char *fname1, const char *fname2, char *list) {
175 183
176 // build pre-exec filter: whitelist also @default-keep 184 // build pre-exec filter: whitelist also @default-keep
177 filter_init(fd); 185 filter_init(fd);
186
187 // allow exceptions in form of !syscall
188 syscall_check_list(list, filter_add_blacklist_for_excluded, fd, 0, NULL);
189
178 // 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
179 int r; 191 int r;
180 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);
diff --git a/src/fseccomp/seccomp_file.c b/src/fseccomp/seccomp_file.c
index 2e1f317ed..266ef0c55 100644
--- a/src/fseccomp/seccomp_file.c
+++ b/src/fseccomp/seccomp_file.c
@@ -60,26 +60,58 @@ 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
63void filter_add_whitelist(int fd, int syscall, int arg, void *ptrarg) { 63static void write_whitelist(int fd, int syscall) {
64 (void) arg;
65 (void) ptrarg;
66
67 struct sock_filter filter[] = { 64 struct sock_filter filter[] = {
68 WHITELIST(syscall) 65 WHITELIST(syscall)
69 }; 66 };
70 write_to_file(fd, filter, sizeof(filter)); 67 write_to_file(fd, filter, sizeof(filter));
71} 68}
72 69
73void filter_add_blacklist(int fd, int syscall, int arg, void *ptrarg) { 70static void write_blacklist(int fd, int syscall) {
74 (void) arg;
75 (void) ptrarg;
76
77 struct sock_filter filter[] = { 71 struct sock_filter filter[] = {
78 BLACKLIST(syscall) 72 BLACKLIST(syscall)
79 }; 73 };
80 write_to_file(fd, filter, sizeof(filter)); 74 write_to_file(fd, filter, sizeof(filter));
81} 75}
82 76
77void filter_add_whitelist(int fd, int syscall, int arg, void *ptrarg) {
78 (void) arg;
79 (void) ptrarg;
80
81 if (syscall >= 0) {
82 write_whitelist(fd, syscall);
83 }
84}
85
86// handle seccomp list exceptions (seccomp x,y,!z)
87void filter_add_whitelist_for_excluded(int fd, int syscall, int arg, void *ptrarg) {
88 (void) arg;
89 (void) ptrarg;
90
91 if (syscall < 0) {
92 write_whitelist(fd, -syscall);
93 }
94}
95
96void filter_add_blacklist(int fd, int syscall, int arg, void *ptrarg) {
97 (void) arg;
98 (void) ptrarg;
99
100 if (syscall >= 0) {
101 write_blacklist(fd, syscall);
102 }
103}
104
105// handle seccomp list exceptions (seccomp x,y,!z)
106void filter_add_blacklist_for_excluded(int fd, int syscall, int arg, void *ptrarg) {
107 (void) arg;
108 (void) ptrarg;
109
110 if (syscall < 0) {
111 write_blacklist(fd, -syscall);
112 }
113}
114
83void filter_add_errno(int fd, int syscall, int arg, void *ptrarg) { 115void filter_add_errno(int fd, int syscall, int arg, void *ptrarg) {
84 (void) ptrarg; 116 (void) ptrarg;
85 struct sock_filter filter[] = { 117 struct sock_filter filter[] = {
diff --git a/src/fseccomp/syscall.c b/src/fseccomp/syscall.c
index 3b698d2dd..d31b719d6 100644
--- a/src/fseccomp/syscall.c
+++ b/src/fseccomp/syscall.c
@@ -497,9 +497,17 @@ int syscall_check_list(const char *slist, void (*callback)(int fd, int syscall,
497 syscall_check_list(new_list, callback, fd, arg, ptrarg); 497 syscall_check_list(new_list, callback, fd, arg, ptrarg);
498 } 498 }
499 else { 499 else {
500 bool negate = false;
501 if (*ptr == '!') {
502 negate = true;
503 ptr++;
504 }
500 syscall_process_name(ptr, &syscall_nr, &error_nr); 505 syscall_process_name(ptr, &syscall_nr, &error_nr);
501 if (syscall_nr == -1) {;} 506 if (syscall_nr == -1) {;}
502 else if (callback != NULL) { 507 else if (callback != NULL) {
508 if (negate) {
509 syscall_nr = -syscall_nr;
510 }
503 if (error_nr != -1 && fd != 0) { 511 if (error_nr != -1 && fd != 0) {
504 filter_add_errno(fd, syscall_nr, error_nr, ptrarg); 512 filter_add_errno(fd, syscall_nr, error_nr, ptrarg);
505 } 513 }
@@ -522,7 +530,7 @@ static void find_syscall(int fd, int syscall, int arg, void *ptrarg) {
522 (void)fd; 530 (void)fd;
523 (void) arg; 531 (void) arg;
524 SyscallCheckList *ptr = ptrarg; 532 SyscallCheckList *ptr = ptrarg;
525 if (syscall == ptr->syscall) 533 if (abs(syscall) == ptr->syscall)
526 ptr->found = true; 534 ptr->found = true;
527} 535}
528 536