aboutsummaryrefslogtreecommitdiffstats
path: root/src/firejail/sandbox.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/firejail/sandbox.c')
-rw-r--r--src/firejail/sandbox.c297
1 files changed, 154 insertions, 143 deletions
diff --git a/src/firejail/sandbox.c b/src/firejail/sandbox.c
index 8021ce9a3..3942e4da6 100644
--- a/src/firejail/sandbox.c
+++ b/src/firejail/sandbox.c
@@ -122,7 +122,7 @@ static void sandbox_if_up(Bridge *br) {
122 assert(br); 122 assert(br);
123 if (!br->configured) 123 if (!br->configured)
124 return; 124 return;
125 125
126 char *dev = br->devsandbox; 126 char *dev = br->devsandbox;
127 net_if_up(dev); 127 net_if_up(dev);
128 128
@@ -137,8 +137,7 @@ static void sandbox_if_up(Bridge *br) {
137 assert(br->ipsandbox); 137 assert(br->ipsandbox);
138 if (arg_debug) 138 if (arg_debug)
139 printf("Configuring %d.%d.%d.%d address on interface %s\n", PRINT_IP(br->ipsandbox), dev); 139 printf("Configuring %d.%d.%d.%d address on interface %s\n", PRINT_IP(br->ipsandbox), dev);
140 net_if_ip(dev, br->ipsandbox, br->mask, br->mtu); 140 net_config_interface(dev, br->ipsandbox, br->mask, br->mtu);
141 net_if_up(dev);
142 } 141 }
143 else if (br->arg_ip_none == 0 && br->macvlan == 1) { 142 else if (br->arg_ip_none == 0 && br->macvlan == 1) {
144 // reassign the macvlan address 143 // reassign the macvlan address
@@ -160,8 +159,7 @@ static void sandbox_if_up(Bridge *br) {
160 159
161 if (arg_debug) 160 if (arg_debug)
162 printf("Configuring %d.%d.%d.%d address on interface %s\n", PRINT_IP(br->ipsandbox), dev); 161 printf("Configuring %d.%d.%d.%d address on interface %s\n", PRINT_IP(br->ipsandbox), dev);
163 net_if_ip(dev, br->ipsandbox, br->mask, br->mtu); 162 net_config_interface(dev, br->ipsandbox, br->mask, br->mtu);
164 net_if_up(dev);
165 } 163 }
166 164
167 if (br->ip6sandbox) 165 if (br->ip6sandbox)
@@ -256,32 +254,6 @@ static int monitor_application(pid_t app_pid) {
256 254
257 // return the latest exit status. 255 // return the latest exit status.
258 return status; 256 return status;
259
260#if 0
261// todo: find a way to shut down interfaces before closing the namespace
262// the problem is we don't have enough privileges to shutdown interfaces in this moment
263 // shut down bridge/macvlan interfaces
264 if (any_bridge_configured()) {
265
266 if (cfg.bridge0.configured) {
267 printf("Shutting down %s\n", cfg.bridge0.devsandbox);
268 net_if_down( cfg.bridge0.devsandbox);
269 }
270 if (cfg.bridge1.configured) {
271 printf("Shutting down %s\n", cfg.bridge1.devsandbox);
272 net_if_down( cfg.bridge1.devsandbox);
273 }
274 if (cfg.bridge2.configured) {
275 printf("Shutting down %s\n", cfg.bridge2.devsandbox);
276 net_if_down( cfg.bridge2.devsandbox);
277 }
278 if (cfg.bridge3.configured) {
279 printf("Shutting down %s\n", cfg.bridge3.devsandbox);
280 net_if_down( cfg.bridge3.devsandbox);
281 }
282 usleep(20000); // 20 ms sleep
283 }
284#endif
285} 257}
286 258
287void start_audit(void) { 259void start_audit(void) {
@@ -442,7 +414,8 @@ int sandbox(void* sandbox_arg) {
442 if (mount(NULL, "/", NULL, MS_SLAVE | MS_REC, NULL) < 0) { 414 if (mount(NULL, "/", NULL, MS_SLAVE | MS_REC, NULL) < 0) {
443 chk_chroot(); 415 chk_chroot();
444 } 416 }
445 417 // ... and mount a tmpfs on top of /run/firejail/mnt directory
418 preproc_mount_mnt_dir();
446 419
447 //**************************** 420 //****************************
448 // log sandbox data 421 // log sandbox data
@@ -459,7 +432,7 @@ int sandbox(void* sandbox_arg) {
459 fs_logger("install mount namespace"); 432 fs_logger("install mount namespace");
460 433
461 //**************************** 434 //****************************
462 // netfilter etc. 435 // netfilter
463 //**************************** 436 //****************************
464 if (arg_netfilter && any_bridge_configured()) { // assuming by default the client filter 437 if (arg_netfilter && any_bridge_configured()) { // assuming by default the client filter
465 netfilter(arg_netfilter_file); 438 netfilter(arg_netfilter_file);
@@ -468,6 +441,105 @@ int sandbox(void* sandbox_arg) {
468 netfilter6(arg_netfilter6_file); 441 netfilter6(arg_netfilter6_file);
469 } 442 }
470 443
444 //****************************
445 // networking
446 //****************************
447 int gw_cfg_failed = 0; // default gw configuration flag
448 if (arg_nonetwork) {
449 net_if_up("lo");
450 if (arg_debug)
451 printf("Network namespace enabled, only loopback interface available\n");
452 }
453 else if (any_bridge_configured() || any_interface_configured()) {
454 // configure lo and eth0...eth3
455 net_if_up("lo");
456
457 if (mac_not_zero(cfg.bridge0.macsandbox))
458 net_config_mac(cfg.bridge0.devsandbox, cfg.bridge0.macsandbox);
459 sandbox_if_up(&cfg.bridge0);
460
461 if (mac_not_zero(cfg.bridge1.macsandbox))
462 net_config_mac(cfg.bridge1.devsandbox, cfg.bridge1.macsandbox);
463 sandbox_if_up(&cfg.bridge1);
464
465 if (mac_not_zero(cfg.bridge2.macsandbox))
466 net_config_mac(cfg.bridge2.devsandbox, cfg.bridge2.macsandbox);
467 sandbox_if_up(&cfg.bridge2);
468
469 if (mac_not_zero(cfg.bridge3.macsandbox))
470 net_config_mac(cfg.bridge3.devsandbox, cfg.bridge3.macsandbox);
471 sandbox_if_up(&cfg.bridge3);
472
473
474// todo: this code seems to be dead!!!
475 // enable interfaces
476 if (cfg.interface0.configured && cfg.interface0.ip) {
477assert(0);
478 if (arg_debug)
479 printf("Configuring %d.%d.%d.%d address on interface %s\n", PRINT_IP(cfg.interface0.ip), cfg.interface0.dev);
480 net_config_interface(cfg.interface0.dev, cfg.interface0.ip, cfg.interface0.mask, cfg.interface0.mtu);
481 }
482 if (cfg.interface1.configured && cfg.interface1.ip) {
483assert(0);
484 if (arg_debug)
485 printf("Configuring %d.%d.%d.%d address on interface %s\n", PRINT_IP(cfg.interface1.ip), cfg.interface1.dev);
486 net_config_interface(cfg.interface1.dev, cfg.interface1.ip, cfg.interface1.mask, cfg.interface1.mtu);
487 }
488 if (cfg.interface2.configured && cfg.interface2.ip) {
489assert(0);
490 if (arg_debug)
491 printf("Configuring %d.%d.%d.%d address on interface %s\n", PRINT_IP(cfg.interface2.ip), cfg.interface2.dev);
492 net_config_interface(cfg.interface2.dev, cfg.interface2.ip, cfg.interface2.mask, cfg.interface2.mtu);
493 }
494 if (cfg.interface3.configured && cfg.interface3.ip) {
495assert(0);
496 if (arg_debug)
497 printf("Configuring %d.%d.%d.%d address on interface %s\n", PRINT_IP(cfg.interface3.ip), cfg.interface3.dev);
498 net_config_interface(cfg.interface3.dev, cfg.interface3.ip, cfg.interface3.mask, cfg.interface3.mtu);
499 }
500
501 // add a default route
502 if (cfg.defaultgw) {
503 // set the default route
504 if (net_add_route(0, 0, cfg.defaultgw)) {
505 fprintf(stderr, "Warning: cannot configure default route\n");
506 gw_cfg_failed = 1;
507 }
508 }
509
510 if (arg_debug)
511 printf("Network namespace enabled\n");
512 }
513
514
515 // print network configuration
516 if (!arg_quiet) {
517 if (any_bridge_configured() || any_interface_configured() || cfg.defaultgw || cfg.dns1) {
518 printf("\n");
519 if (any_bridge_configured() || any_interface_configured()) {
520// net_ifprint();
521 if (arg_scan)
522 sbox_run(SBOX_ROOT | SBOX_CAPS_NETWORK | SBOX_SECCOMP, 3, PATH_FNET, "printif", "scan");
523 else
524 sbox_run(SBOX_ROOT | SBOX_CAPS_NETWORK | SBOX_SECCOMP, 2, PATH_FNET, "printif", "scan");
525
526 }
527 if (cfg.defaultgw != 0) {
528 if (gw_cfg_failed)
529 printf("Default gateway configuration failed\n");
530 else
531 printf("Default gateway %d.%d.%d.%d\n", PRINT_IP(cfg.defaultgw));
532 }
533 if (cfg.dns1 != 0)
534 printf("DNS server %d.%d.%d.%d\n", PRINT_IP(cfg.dns1));
535 if (cfg.dns2 != 0)
536 printf("DNS server %d.%d.%d.%d\n", PRINT_IP(cfg.dns2));
537 if (cfg.dns3 != 0)
538 printf("DNS server %d.%d.%d.%d\n", PRINT_IP(cfg.dns3));
539 printf("\n");
540 }
541 }
542
471 // load IBUS env variables 543 // load IBUS env variables
472 if (arg_nonetwork || any_bridge_configured() || any_interface_configured()) { 544 if (arg_nonetwork || any_bridge_configured() || any_interface_configured()) {
473 // do nothing - there are problems with ibus version 1.5.11 545 // do nothing - there are problems with ibus version 1.5.11
@@ -475,9 +547,27 @@ int sandbox(void* sandbox_arg) {
475 else 547 else
476 env_ibus_load(); 548 env_ibus_load();
477 549
478 // grab a copy of cp command 550 //****************************
479 fs_build_cp_command(); 551 // fs pre-processing:
480 552 // - copy some commands under /run
553 // - build seccomp filters
554 // - create an empty /etc/ld.so.preload
555 //****************************
556 preproc_build_cp_command();
557
558#ifdef HAVE_SECCOMP
559 if (cfg.protocol) {
560 if (arg_debug)
561 printf("Build protocol filter: %s\n", cfg.protocol);
562
563 // build the seccomp filter as a regular user
564 int rv = sbox_run(SBOX_USER | SBOX_CAPS_NONE | SBOX_SECCOMP, 5,
565 PATH_FSECCOMP, "protocol", "build", cfg.protocol, RUN_SECCOMP_PROTOCOL);
566 if (rv)
567 exit(rv);
568 }
569#endif
570
481 // trace pre-install 571 // trace pre-install
482 if (arg_trace || arg_tracelog || mask_x11_abstract_socket) 572 if (arg_trace || arg_tracelog || mask_x11_abstract_socket)
483 fs_trace_preload(); 573 fs_trace_preload();
@@ -488,6 +578,13 @@ int sandbox(void* sandbox_arg) {
488#ifdef HAVE_SECCOMP 578#ifdef HAVE_SECCOMP
489 int enforce_seccomp = 0; 579 int enforce_seccomp = 0;
490#endif 580#endif
581 if (arg_appimage) {
582 enforce_filters();
583#ifdef HAVE_SECCOMP
584 enforce_seccomp = 1;
585#endif
586 }
587
491#ifdef HAVE_CHROOT 588#ifdef HAVE_CHROOT
492 if (cfg.chrootdir) { 589 if (cfg.chrootdir) {
493 fs_chroot(cfg.chrootdir); 590 fs_chroot(cfg.chrootdir);
@@ -610,7 +707,6 @@ int sandbox(void* sandbox_arg) {
610 EUID_USER(); 707 EUID_USER();
611 profile_add("whitelist /tmp/.X11-unix"); 708 profile_add("whitelist /tmp/.X11-unix");
612 EUID_ROOT(); 709 EUID_ROOT();
613// fs_private_tmp();
614 } 710 }
615 } 711 }
616 712
@@ -657,102 +753,17 @@ int sandbox(void* sandbox_arg) {
657 fs_dev_disable_3d(); 753 fs_dev_disable_3d();
658 754
659 //**************************** 755 //****************************
660 // networking 756 // set dns
661 //**************************** 757 //****************************
662 int gw_cfg_failed = 0; // default gw configuration flag
663 if (arg_nonetwork) {
664 net_if_up("lo");
665 if (arg_debug)
666 printf("Network namespace enabled, only loopback interface available\n");
667 }
668 else if (any_bridge_configured() || any_interface_configured()) {
669 // configure lo and eth0...eth3
670 net_if_up("lo");
671
672 if (mac_not_zero(cfg.bridge0.macsandbox))
673 net_config_mac(cfg.bridge0.devsandbox, cfg.bridge0.macsandbox);
674 sandbox_if_up(&cfg.bridge0);
675
676 if (mac_not_zero(cfg.bridge1.macsandbox))
677 net_config_mac(cfg.bridge1.devsandbox, cfg.bridge1.macsandbox);
678 sandbox_if_up(&cfg.bridge1);
679
680 if (mac_not_zero(cfg.bridge2.macsandbox))
681 net_config_mac(cfg.bridge2.devsandbox, cfg.bridge2.macsandbox);
682 sandbox_if_up(&cfg.bridge2);
683
684 if (mac_not_zero(cfg.bridge3.macsandbox))
685 net_config_mac(cfg.bridge3.devsandbox, cfg.bridge3.macsandbox);
686 sandbox_if_up(&cfg.bridge3);
687
688 // enable interfaces
689 if (cfg.interface0.configured && cfg.interface0.ip) {
690 if (arg_debug)
691 printf("Configuring %d.%d.%d.%d address on interface %s\n", PRINT_IP(cfg.interface0.ip), cfg.interface0.dev);
692 net_if_ip(cfg.interface0.dev, cfg.interface0.ip, cfg.interface0.mask, cfg.interface0.mtu);
693 net_if_up(cfg.interface0.dev);
694 }
695 if (cfg.interface1.configured && cfg.interface1.ip) {
696 if (arg_debug)
697 printf("Configuring %d.%d.%d.%d address on interface %s\n", PRINT_IP(cfg.interface1.ip), cfg.interface1.dev);
698 net_if_ip(cfg.interface1.dev, cfg.interface1.ip, cfg.interface1.mask, cfg.interface1.mtu);
699 net_if_up(cfg.interface1.dev);
700 }
701 if (cfg.interface2.configured && cfg.interface2.ip) {
702 if (arg_debug)
703 printf("Configuring %d.%d.%d.%d address on interface %s\n", PRINT_IP(cfg.interface2.ip), cfg.interface2.dev);
704 net_if_ip(cfg.interface2.dev, cfg.interface2.ip, cfg.interface2.mask, cfg.interface2.mtu);
705 net_if_up(cfg.interface2.dev);
706 }
707 if (cfg.interface3.configured && cfg.interface3.ip) {
708 if (arg_debug)
709 printf("Configuring %d.%d.%d.%d address on interface %s\n", PRINT_IP(cfg.interface3.ip), cfg.interface3.dev);
710 net_if_ip(cfg.interface3.dev, cfg.interface3.ip, cfg.interface3.mask, cfg.interface3.mtu);
711 net_if_up(cfg.interface3.dev);
712 }
713
714 // add a default route
715 if (cfg.defaultgw) {
716 // set the default route
717 if (net_add_route(0, 0, cfg.defaultgw)) {
718 fprintf(stderr, "Warning: cannot configure default route\n");
719 gw_cfg_failed = 1;
720 }
721 }
722
723 if (arg_debug)
724 printf("Network namespace enabled\n");
725 }
726
727 // if any dns server is configured, it is time to set it now
728 fs_resolvconf(); 758 fs_resolvconf();
759
760 //****************************
761 // fs post-processing
762 //****************************
763 preproc_delete_cp_command();
729 fs_logger_print(); 764 fs_logger_print();
730 fs_logger_change_owner(); 765 fs_logger_change_owner();
731 766
732 // print network configuration
733 if (!arg_quiet) {
734 if (any_bridge_configured() || any_interface_configured() || cfg.defaultgw || cfg.dns1) {
735 printf("\n");
736 if (any_bridge_configured() || any_interface_configured())
737 net_ifprint();
738 if (cfg.defaultgw != 0) {
739 if (gw_cfg_failed)
740 printf("Default gateway configuration failed\n");
741 else
742 printf("Default gateway %d.%d.%d.%d\n", PRINT_IP(cfg.defaultgw));
743 }
744 if (cfg.dns1 != 0)
745 printf("DNS server %d.%d.%d.%d\n", PRINT_IP(cfg.dns1));
746 if (cfg.dns2 != 0)
747 printf("DNS server %d.%d.%d.%d\n", PRINT_IP(cfg.dns2));
748 if (cfg.dns3 != 0)
749 printf("DNS server %d.%d.%d.%d\n", PRINT_IP(cfg.dns3));
750 printf("\n");
751 }
752 }
753
754 fs_delete_cp_command();
755
756 //**************************** 767 //****************************
757 // set application environment 768 // set application environment
758 //**************************** 769 //****************************
@@ -808,12 +819,24 @@ int sandbox(void* sandbox_arg) {
808 // set rlimits 819 // set rlimits
809 set_rlimits(); 820 set_rlimits();
810 821
811 // set seccomp 822 // set cpu affinity
823 if (cfg.cpus) {
824 save_cpu(); // save cpu affinity mask to CPU_CFG file
825 set_cpu_affinity();
826 }
827
828 // save cgroup in CGROUP_CFG file
829 if (cfg.cgroup)
830 save_cgroup();
831
832 // set seccomp //todo: push it down after drop_privs and/or configuring noroot
812#ifdef HAVE_SECCOMP 833#ifdef HAVE_SECCOMP
813 // install protocol filter 834 // install protocol filter
814 if (cfg.protocol) { 835 if (cfg.protocol) {
815 protocol_filter(); // install filter 836 if (arg_debug)
816 protocol_filter_save(); // save filter in PROTOCOL_CFG 837 printf("Install protocol filter: %s\n", cfg.protocol);
838 seccomp_load(RUN_SECCOMP_PROTOCOL); // install filter
839 protocol_filter_save(); // save filter in RUN_PROTOCOL_CFG
817 } 840 }
818 841
819 // if a keep list is available, disregard the drop list 842 // if a keep list is available, disregard the drop list
@@ -827,16 +850,6 @@ int sandbox(void* sandbox_arg) {
827 } 850 }
828#endif 851#endif
829 852
830 // set cpu affinity
831 if (cfg.cpus) {
832 save_cpu(); // save cpu affinity mask to CPU_CFG file
833 set_cpu_affinity();
834 }
835
836 // save cgroup in CGROUP_CFG file
837 if (cfg.cgroup)
838 save_cgroup();
839
840 //**************************************** 853 //****************************************
841 // drop privileges or create a new user namespace 854 // drop privileges or create a new user namespace
842 //**************************************** 855 //****************************************
@@ -909,8 +922,6 @@ int sandbox(void* sandbox_arg) {
909 int status = monitor_application(app_pid); // monitor application 922 int status = monitor_application(app_pid); // monitor application
910 flush_stdin(); 923 flush_stdin();
911 924
912
913
914 if (WIFEXITED(status)) { 925 if (WIFEXITED(status)) {
915 // if we had a proper exit, return that exit status 926 // if we had a proper exit, return that exit status
916 return WEXITSTATUS(status); 927 return WEXITSTATUS(status);