diff options
author | Topi Miettinen <toiwoton@gmail.com> | 2020-03-14 00:07:06 +0200 |
---|---|---|
committer | Topi Miettinen <topimiettinen@users.noreply.github.com> | 2020-03-28 11:24:25 +0000 |
commit | 88eadbf31fe25dcd7c224a5d92f71c79ccf6c9d3 (patch) | |
tree | 6b4d2a805a2900755bfc857586a10948b3c8395e /src/firejail/main.c | |
parent | Added compatibility with BetterDiscord (#3300) (diff) | |
download | firejail-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/firejail/main.c')
-rw-r--r-- | src/firejail/main.c | 70 |
1 files changed, 70 insertions, 0 deletions
diff --git a/src/firejail/main.c b/src/firejail/main.c index 78717ab41..922ba2edb 100644 --- a/src/firejail/main.c +++ b/src/firejail/main.c | |||
@@ -20,6 +20,7 @@ | |||
20 | #include "firejail.h" | 20 | #include "firejail.h" |
21 | #include "../include/pid.h" | 21 | #include "../include/pid.h" |
22 | #include "../include/firejail_user.h" | 22 | #include "../include/firejail_user.h" |
23 | #include "../include/syscall.h" | ||
23 | #define _GNU_SOURCE | 24 | #define _GNU_SOURCE |
24 | #include <sys/utsname.h> | 25 | #include <sys/utsname.h> |
25 | #include <sched.h> | 26 | #include <sched.h> |
@@ -72,6 +73,7 @@ int arg_overlay_keep = 0; // place overlay diff in a known directory | |||
72 | int arg_overlay_reuse = 0; // allow the reuse of overlays | 73 | int arg_overlay_reuse = 0; // allow the reuse of overlays |
73 | 74 | ||
74 | int arg_seccomp = 0; // enable default seccomp filter | 75 | int arg_seccomp = 0; // enable default seccomp filter |
76 | int arg_seccomp32 = 0; // enable default seccomp filter for 32 bit arch | ||
75 | int arg_seccomp_postexec = 0; // need postexec ld.preload library? | 77 | int arg_seccomp_postexec = 0; // need postexec ld.preload library? |
76 | int arg_seccomp_block_secondary = 0; // block any secondary architectures | 78 | int arg_seccomp_block_secondary = 0; // block any secondary architectures |
77 | 79 | ||
@@ -548,6 +550,14 @@ static void run_cmd_and_exit(int i, int argc, char **argv) { | |||
548 | else | 550 | else |
549 | exit_err_feature("seccomp"); | 551 | exit_err_feature("seccomp"); |
550 | } | 552 | } |
553 | else if (strcmp(argv[i], "--debug-syscalls32") == 0) { | ||
554 | if (checkcfg(CFG_SECCOMP)) { | ||
555 | int rv = sbox_run(SBOX_USER | SBOX_CAPS_NONE | SBOX_SECCOMP, 2, PATH_FSECCOMP_MAIN, "debug-syscalls32"); | ||
556 | exit(rv); | ||
557 | } | ||
558 | else | ||
559 | exit_err_feature("seccomp"); | ||
560 | } | ||
551 | else if (strcmp(argv[i], "--debug-errnos") == 0) { | 561 | else if (strcmp(argv[i], "--debug-errnos") == 0) { |
552 | if (checkcfg(CFG_SECCOMP)) { | 562 | if (checkcfg(CFG_SECCOMP)) { |
553 | int rv = sbox_run(SBOX_USER | SBOX_CAPS_NONE | SBOX_SECCOMP, 2, PATH_FSECCOMP_MAIN, "debug-errnos"); | 563 | int rv = sbox_run(SBOX_USER | SBOX_CAPS_NONE | SBOX_SECCOMP, 2, PATH_FSECCOMP_MAIN, "debug-errnos"); |
@@ -956,6 +966,18 @@ static void run_builder(int argc, char **argv) { | |||
956 | exit(1); | 966 | exit(1); |
957 | } | 967 | } |
958 | 968 | ||
969 | void filter_add_errno(int fd, int syscall, int arg, void *ptrarg, bool native) {} | ||
970 | |||
971 | static int check_postexec(const char *list) { | ||
972 | char *prelist, *postlist; | ||
973 | |||
974 | if (list) { | ||
975 | syscalls_in_list(list, "@default-keep", -1, &prelist, &postlist, true); | ||
976 | if (postlist) | ||
977 | return 1; | ||
978 | } | ||
979 | return 0; | ||
980 | } | ||
959 | 981 | ||
960 | //******************************************* | 982 | //******************************************* |
961 | // Main program | 983 | // Main program |
@@ -1263,6 +1285,18 @@ int main(int argc, char **argv) { | |||
1263 | else | 1285 | else |
1264 | exit_err_feature("seccomp"); | 1286 | exit_err_feature("seccomp"); |
1265 | } | 1287 | } |
1288 | else if (strncmp(argv[i], "--seccomp.32=", 13) == 0) { | ||
1289 | if (checkcfg(CFG_SECCOMP)) { | ||
1290 | if (arg_seccomp32) { | ||
1291 | fprintf(stderr, "Error: seccomp.32 already enabled\n"); | ||
1292 | exit(1); | ||
1293 | } | ||
1294 | arg_seccomp32 = 1; | ||
1295 | cfg.seccomp_list32 = seccomp_check_list(argv[i] + 13); | ||
1296 | } | ||
1297 | else | ||
1298 | exit_err_feature("seccomp"); | ||
1299 | } | ||
1266 | else if (strncmp(argv[i], "--seccomp.drop=", 15) == 0) { | 1300 | else if (strncmp(argv[i], "--seccomp.drop=", 15) == 0) { |
1267 | if (checkcfg(CFG_SECCOMP)) { | 1301 | if (checkcfg(CFG_SECCOMP)) { |
1268 | if (arg_seccomp) { | 1302 | if (arg_seccomp) { |
@@ -1275,6 +1309,18 @@ int main(int argc, char **argv) { | |||
1275 | else | 1309 | else |
1276 | exit_err_feature("seccomp"); | 1310 | exit_err_feature("seccomp"); |
1277 | } | 1311 | } |
1312 | else if (strncmp(argv[i], "--seccomp.32.drop=", 18) == 0) { | ||
1313 | if (checkcfg(CFG_SECCOMP)) { | ||
1314 | if (arg_seccomp32) { | ||
1315 | fprintf(stderr, "Error: seccomp.32 already enabled\n"); | ||
1316 | exit(1); | ||
1317 | } | ||
1318 | arg_seccomp32 = 1; | ||
1319 | cfg.seccomp_list_drop32 = seccomp_check_list(argv[i] + 18); | ||
1320 | } | ||
1321 | else | ||
1322 | exit_err_feature("seccomp"); | ||
1323 | } | ||
1278 | else if (strncmp(argv[i], "--seccomp.keep=", 15) == 0) { | 1324 | else if (strncmp(argv[i], "--seccomp.keep=", 15) == 0) { |
1279 | if (checkcfg(CFG_SECCOMP)) { | 1325 | if (checkcfg(CFG_SECCOMP)) { |
1280 | if (arg_seccomp) { | 1326 | if (arg_seccomp) { |
@@ -1287,8 +1333,24 @@ int main(int argc, char **argv) { | |||
1287 | else | 1333 | else |
1288 | exit_err_feature("seccomp"); | 1334 | exit_err_feature("seccomp"); |
1289 | } | 1335 | } |
1336 | else if (strncmp(argv[i], "--seccomp.32.keep=", 18) == 0) { | ||
1337 | if (checkcfg(CFG_SECCOMP)) { | ||
1338 | if (arg_seccomp32) { | ||
1339 | fprintf(stderr, "Error: seccomp.32 already enabled\n"); | ||
1340 | exit(1); | ||
1341 | } | ||
1342 | arg_seccomp32 = 1; | ||
1343 | cfg.seccomp_list_keep32 = seccomp_check_list(argv[i] + 18); | ||
1344 | } | ||
1345 | else | ||
1346 | exit_err_feature("seccomp"); | ||
1347 | } | ||
1290 | else if (strcmp(argv[i], "--seccomp.block-secondary") == 0) { | 1348 | else if (strcmp(argv[i], "--seccomp.block-secondary") == 0) { |
1291 | if (checkcfg(CFG_SECCOMP)) { | 1349 | if (checkcfg(CFG_SECCOMP)) { |
1350 | if (arg_seccomp32) { | ||
1351 | fprintf(stderr, "Error: seccomp.32 conflicts with block-secondary\n"); | ||
1352 | exit(1); | ||
1353 | } | ||
1292 | arg_seccomp_block_secondary = 1; | 1354 | arg_seccomp_block_secondary = 1; |
1293 | } | 1355 | } |
1294 | else | 1356 | else |
@@ -2542,6 +2604,14 @@ int main(int argc, char **argv) { | |||
2542 | // check network configuration options - it will exit if anything went wrong | 2604 | // check network configuration options - it will exit if anything went wrong |
2543 | net_check_cfg(); | 2605 | net_check_cfg(); |
2544 | 2606 | ||
2607 | #ifdef HAVE_SECCOMP | ||
2608 | if (arg_seccomp) | ||
2609 | arg_seccomp_postexec = check_postexec(cfg.seccomp_list) || check_postexec(cfg.seccomp_list_drop); | ||
2610 | #endif | ||
2611 | bool need_preload = arg_trace || arg_tracelog || arg_seccomp_postexec; | ||
2612 | if (need_preload && (cfg.seccomp_list32 || cfg.seccomp_list_drop32 || cfg.seccomp_list_keep32)) | ||
2613 | fwarning("preload libraries (trace, tracelog, postexecseccomp due to seccomp.drop=execve etc.) are incompatible with 32 bit filters\n"); | ||
2614 | |||
2545 | // check and assign an IP address - for macvlan it will be done again in the sandbox! | 2615 | // check and assign an IP address - for macvlan it will be done again in the sandbox! |
2546 | if (any_bridge_configured()) { | 2616 | if (any_bridge_configured()) { |
2547 | EUID_ROOT(); | 2617 | EUID_ROOT(); |