aboutsummaryrefslogtreecommitdiffstats
path: root/src/firejail/main.c
diff options
context:
space:
mode:
authorLibravatar Topi Miettinen <toiwoton@gmail.com>2020-03-14 00:07:06 +0200
committerLibravatar Topi Miettinen <topimiettinen@users.noreply.github.com>2020-03-28 11:24:25 +0000
commit88eadbf31fe25dcd7c224a5d92f71c79ccf6c9d3 (patch)
tree6b4d2a805a2900755bfc857586a10948b3c8395e /src/firejail/main.c
parentAdded compatibility with BetterDiscord (#3300) (diff)
downloadfirejail-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.c70
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
72int arg_overlay_reuse = 0; // allow the reuse of overlays 73int arg_overlay_reuse = 0; // allow the reuse of overlays
73 74
74int arg_seccomp = 0; // enable default seccomp filter 75int arg_seccomp = 0; // enable default seccomp filter
76int arg_seccomp32 = 0; // enable default seccomp filter for 32 bit arch
75int arg_seccomp_postexec = 0; // need postexec ld.preload library? 77int arg_seccomp_postexec = 0; // need postexec ld.preload library?
76int arg_seccomp_block_secondary = 0; // block any secondary architectures 78int 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
969void filter_add_errno(int fd, int syscall, int arg, void *ptrarg, bool native) {}
970
971static 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();