diff options
author | Topi Miettinen <toiwoton@gmail.com> | 2020-03-27 14:22:20 +0200 |
---|---|---|
committer | Topi Miettinen <topimiettinen@users.noreply.github.com> | 2020-04-06 16:30:20 +0000 |
commit | 3f27e8483158e50050f839db343bda7a522f686d (patch) | |
tree | d8dad893d71220ff97aa7744fe7e62900075e521 /src/lib | |
parent | cleanup, fixes, more profstats (diff) | |
download | firejail-3f27e8483158e50050f839db343bda7a522f686d.tar.gz firejail-3f27e8483158e50050f839db343bda7a522f686d.tar.zst firejail-3f27e8483158e50050f839db343bda7a522f686d.zip |
Allow changing error action in seccomp filters
Let user specify the action when seccomp filters trigger:
- errno name like EPERM (default) or ENOSYS: return errno and let the process continue.
- 'kill': kill the process as previous versions
The default action is EPERM, but killing can still be specified with
syscall:kill syntax or globally with seccomp-error-action=kill. The
action can be also overridden /etc/firejail/firejail.config file.
Not killing the process weakens Firejail slightly when trying to
contain intrusion, but it may also allow tighter filters if the
only alternative is to allow a system call.
Diffstat (limited to 'src/lib')
-rw-r--r-- | src/lib/syscall.c | 31 |
1 files changed, 20 insertions, 11 deletions
diff --git a/src/lib/syscall.c b/src/lib/syscall.c index 1cf7f2d52..5accdcb65 100644 --- a/src/lib/syscall.c +++ b/src/lib/syscall.c | |||
@@ -20,11 +20,16 @@ | |||
20 | #define _GNU_SOURCE | 20 | #define _GNU_SOURCE |
21 | #include "../include/syscall.h" | 21 | #include "../include/syscall.h" |
22 | #include <assert.h> | 22 | #include <assert.h> |
23 | #include <limits.h> | ||
23 | #include <stdbool.h> | 24 | #include <stdbool.h> |
24 | #include <stdio.h> | 25 | #include <stdio.h> |
25 | #include <string.h> | 26 | #include <string.h> |
26 | #include <sys/syscall.h> | 27 | #include <sys/syscall.h> |
27 | #include "../include/common.h" | 28 | #include "../include/common.h" |
29 | #include "../include/seccomp.h" | ||
30 | |||
31 | #define SYSCALL_ERROR INT_MAX | ||
32 | #define ERRNO_KILL -2 | ||
28 | 33 | ||
29 | typedef struct { | 34 | typedef struct { |
30 | const char * const name; | 35 | const char * const name; |
@@ -1430,7 +1435,7 @@ static const SyscallGroupList sysgroups[] = { | |||
1430 | } | 1435 | } |
1431 | }; | 1436 | }; |
1432 | 1437 | ||
1433 | // return -1 if error, or syscall number | 1438 | // return SYSCALL_ERROR if error, or syscall number |
1434 | static int syscall_find_name(const char *name) { | 1439 | static int syscall_find_name(const char *name) { |
1435 | int i; | 1440 | int i; |
1436 | int elems = sizeof(syslist) / sizeof(syslist[0]); | 1441 | int elems = sizeof(syslist) / sizeof(syslist[0]); |
@@ -1439,7 +1444,7 @@ static int syscall_find_name(const char *name) { | |||
1439 | return syslist[i].nr; | 1444 | return syslist[i].nr; |
1440 | } | 1445 | } |
1441 | 1446 | ||
1442 | return -1; | 1447 | return SYSCALL_ERROR; |
1443 | } | 1448 | } |
1444 | 1449 | ||
1445 | static int syscall_find_name_32(const char *name) { | 1450 | static int syscall_find_name_32(const char *name) { |
@@ -1450,7 +1455,7 @@ static int syscall_find_name_32(const char *name) { | |||
1450 | return syslist32[i].nr; | 1455 | return syslist32[i].nr; |
1451 | } | 1456 | } |
1452 | 1457 | ||
1453 | return -1; | 1458 | return SYSCALL_ERROR; |
1454 | } | 1459 | } |
1455 | 1460 | ||
1456 | const char *syscall_find_nr(int nr) { | 1461 | const char *syscall_find_nr(int nr) { |
@@ -1538,9 +1543,13 @@ static void syscall_process_name(const char *name, int *syscall_nr, int *error_n | |||
1538 | *syscall_nr = syscall_find_name_32(syscall_name); | 1543 | *syscall_nr = syscall_find_name_32(syscall_name); |
1539 | } | 1544 | } |
1540 | if (error_name) { | 1545 | if (error_name) { |
1541 | *error_nr = errno_find_name(error_name); | 1546 | if (strcmp(error_name, "kill") == 0) |
1542 | if (*error_nr == -1) | 1547 | *error_nr = ERRNO_KILL; |
1543 | *syscall_nr = -1; | 1548 | else { |
1549 | *error_nr = errno_find_name(error_name); | ||
1550 | if (*error_nr == -1) | ||
1551 | *syscall_nr = SYSCALL_ERROR; | ||
1552 | } | ||
1544 | } | 1553 | } |
1545 | 1554 | ||
1546 | free(str); | 1555 | free(str); |
@@ -1589,15 +1598,15 @@ int syscall_check_list(const char *slist, filter_fn *callback, int fd, int arg, | |||
1589 | ptr++; | 1598 | ptr++; |
1590 | } | 1599 | } |
1591 | syscall_process_name(ptr, &syscall_nr, &error_nr, native); | 1600 | syscall_process_name(ptr, &syscall_nr, &error_nr, native); |
1592 | if (syscall_nr == -1) {;} | 1601 | if (syscall_nr != SYSCALL_ERROR && callback != NULL) { |
1593 | else if (callback != NULL) { | ||
1594 | if (negate) { | 1602 | if (negate) { |
1595 | syscall_nr = -syscall_nr; | 1603 | syscall_nr = -syscall_nr; |
1596 | } | 1604 | } |
1597 | if (error_nr != -1 && fd > 0) { | 1605 | if (error_nr >= 0 && fd > 0) |
1598 | filter_add_errno(fd, syscall_nr, error_nr, ptrarg, native); | 1606 | filter_add_errno(fd, syscall_nr, error_nr, ptrarg, native); |
1599 | } | 1607 | else if (error_nr == ERRNO_KILL && fd > 0) |
1600 | else if (error_nr != -1 && fd == 0) { | 1608 | filter_add_blacklist_override(fd, syscall_nr, 0, ptrarg, native); |
1609 | else if (error_nr >= 0 && fd == 0) { | ||
1601 | callback(fd, syscall_nr, error_nr, ptrarg, native); | 1610 | callback(fd, syscall_nr, error_nr, ptrarg, native); |
1602 | } | 1611 | } |
1603 | else { | 1612 | else { |