summaryrefslogtreecommitdiffstats
path: root/src/fseccomp/syscall.c
diff options
context:
space:
mode:
authorLibravatar Topi Miettinen <toiwoton@gmail.com>2017-08-13 14:07:31 +0300
committerLibravatar Topi Miettinen <toiwoton@gmail.com>2017-08-13 17:31:07 +0300
commit63e9d849f662d1a494c6396d4a439cd4c91dfa7e (patch)
tree703cc8c9c0eb5b9e528f025961df7f322f797737 /src/fseccomp/syscall.c
parentmerges (diff)
downloadfirejail-63e9d849f662d1a494c6396d4a439cd4c91dfa7e.tar.gz
firejail-63e9d849f662d1a494c6396d4a439cd4c91dfa7e.tar.zst
firejail-63e9d849f662d1a494c6396d4a439cd4c91dfa7e.zip
Allow any syscall to be blacklisted (#1447)
Allow any syscall to be blacklisted with aid of LD_PRELOAD library, libpostexecseccomp.so. Closes: #1447
Diffstat (limited to 'src/fseccomp/syscall.c')
-rw-r--r--src/fseccomp/syscall.c64
1 files changed, 60 insertions, 4 deletions
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
23typedef struct { 25typedef struct {
@@ -30,6 +32,13 @@ typedef struct {
30 const char * const list; 32 const char * const list;
31} SyscallGroupList; 33} SyscallGroupList;
32 34
35typedef struct {
36 const char *slist;
37 char *prelist, *postlist;
38 bool found;
39 int syscall;
40} SyscallCheckList;
41
33static const SyscallEntry syslist[] = { 42static 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
452int syscall_check_list(const char *slist, void (*callback)(int fd, int syscall, int arg), int fd, int arg) { 462int 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
512static 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
520static 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
545void 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}