diff options
Diffstat (limited to 'src/firejail/sandbox.c')
-rw-r--r-- | src/firejail/sandbox.c | 144 |
1 files changed, 76 insertions, 68 deletions
diff --git a/src/firejail/sandbox.c b/src/firejail/sandbox.c index 3ff104d26..0b4d63c1b 100644 --- a/src/firejail/sandbox.c +++ b/src/firejail/sandbox.c | |||
@@ -17,7 +17,7 @@ | |||
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 | 20 | ||
21 | #include "firejail.h" | 21 | #include "firejail.h" |
22 | #include <sys/mount.h> | 22 | #include <sys/mount.h> |
23 | #include <sys/wait.h> | 23 | #include <sys/wait.h> |
@@ -65,7 +65,7 @@ static void sandbox_handler(int sig){ | |||
65 | FILE *fp = fopen(monfile, "r"); | 65 | FILE *fp = fopen(monfile, "r"); |
66 | if (!fp) | 66 | if (!fp) |
67 | break; | 67 | break; |
68 | 68 | ||
69 | char c; | 69 | char c; |
70 | size_t count = fread(&c, 1, 1, fp); | 70 | size_t count = fread(&c, 1, 1, fp); |
71 | fclose(fp); | 71 | fclose(fp); |
@@ -78,7 +78,7 @@ static void sandbox_handler(int sig){ | |||
78 | monsec--; | 78 | monsec--; |
79 | } | 79 | } |
80 | free(monfile); | 80 | free(monfile); |
81 | 81 | ||
82 | } | 82 | } |
83 | 83 | ||
84 | 84 | ||
@@ -115,7 +115,7 @@ void save_nogroups(void) { | |||
115 | fprintf(stderr, "Error: cannot save nogroups state\n"); | 115 | fprintf(stderr, "Error: cannot save nogroups state\n"); |
116 | exit(1); | 116 | exit(1); |
117 | } | 117 | } |
118 | 118 | ||
119 | } | 119 | } |
120 | 120 | ||
121 | static void sandbox_if_up(Bridge *br) { | 121 | static void sandbox_if_up(Bridge *br) { |
@@ -132,7 +132,7 @@ static void sandbox_if_up(Bridge *br) { | |||
132 | fprintf(stderr, "Error: %d.%d.%d.%d is interface %s address.\n", PRINT_IP(br->ipsandbox), br->dev); | 132 | fprintf(stderr, "Error: %d.%d.%d.%d is interface %s address.\n", PRINT_IP(br->ipsandbox), br->dev); |
133 | exit(1); | 133 | exit(1); |
134 | } | 134 | } |
135 | 135 | ||
136 | // just assign the address | 136 | // just assign the address |
137 | assert(br->ipsandbox); | 137 | assert(br->ipsandbox); |
138 | if (arg_debug) | 138 | if (arg_debug) |
@@ -149,19 +149,19 @@ static void sandbox_if_up(Bridge *br) { | |||
149 | fprintf(stderr, "Error: %d.%d.%d.%d is interface %s address.\n", PRINT_IP(br->ipsandbox), br->dev); | 149 | fprintf(stderr, "Error: %d.%d.%d.%d is interface %s address.\n", PRINT_IP(br->ipsandbox), br->dev); |
150 | exit(1); | 150 | exit(1); |
151 | } | 151 | } |
152 | 152 | ||
153 | uint32_t rv = arp_check(dev, br->ipsandbox, br->ip); | 153 | uint32_t rv = arp_check(dev, br->ipsandbox, br->ip); |
154 | if (rv) { | 154 | if (rv) { |
155 | fprintf(stderr, "Error: the address %d.%d.%d.%d is already in use.\n", PRINT_IP(br->ipsandbox)); | 155 | fprintf(stderr, "Error: the address %d.%d.%d.%d is already in use.\n", PRINT_IP(br->ipsandbox)); |
156 | exit(1); | 156 | exit(1); |
157 | } | 157 | } |
158 | } | 158 | } |
159 | 159 | ||
160 | if (arg_debug) | 160 | if (arg_debug) |
161 | 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); |
162 | net_config_interface(dev, br->ipsandbox, br->mask, br->mtu); | 162 | net_config_interface(dev, br->ipsandbox, br->mask, br->mtu); |
163 | } | 163 | } |
164 | 164 | ||
165 | if (br->ip6sandbox) | 165 | if (br->ip6sandbox) |
166 | net_if_ip6(dev, br->ip6sandbox); | 166 | net_if_ip6(dev, br->ip6sandbox); |
167 | } | 167 | } |
@@ -171,14 +171,14 @@ static void chk_chroot(void) { | |||
171 | char *mycont = getenv("container"); | 171 | char *mycont = getenv("container"); |
172 | if (mycont) | 172 | if (mycont) |
173 | return; | 173 | return; |
174 | 174 | ||
175 | // check if this is a regular chroot | 175 | // check if this is a regular chroot |
176 | struct stat s; | 176 | struct stat s; |
177 | if (stat("/", &s) == 0) { | 177 | if (stat("/", &s) == 0) { |
178 | if (s.st_ino != 2) | 178 | if (s.st_ino != 2) |
179 | return; | 179 | return; |
180 | } | 180 | } |
181 | 181 | ||
182 | fprintf(stderr, "Error: cannot mount filesystem as slave\n"); | 182 | fprintf(stderr, "Error: cannot mount filesystem as slave\n"); |
183 | exit(1); | 183 | exit(1); |
184 | } | 184 | } |
@@ -238,7 +238,7 @@ static int monitor_application(pid_t app_pid) { | |||
238 | continue; | 238 | continue; |
239 | if (pid == 1) | 239 | if (pid == 1) |
240 | continue; | 240 | continue; |
241 | 241 | ||
242 | // todo: make this generic | 242 | // todo: make this generic |
243 | // Dillo browser leaves a dpid process running, we need to shut it down | 243 | // Dillo browser leaves a dpid process running, we need to shut it down |
244 | int found = 0; | 244 | int found = 0; |
@@ -268,7 +268,7 @@ void start_audit(void) { | |||
268 | char *audit_prog; | 268 | char *audit_prog; |
269 | if (asprintf(&audit_prog, "%s/firejail/faudit", LIBDIR) == -1) | 269 | if (asprintf(&audit_prog, "%s/firejail/faudit", LIBDIR) == -1) |
270 | errExit("asprintf"); | 270 | errExit("asprintf"); |
271 | assert(getenv("LD_PRELOAD") == NULL); | 271 | assert(getenv("LD_PRELOAD") == NULL); |
272 | execl(audit_prog, audit_prog, NULL); | 272 | execl(audit_prog, audit_prog, NULL); |
273 | perror("execl"); | 273 | perror("execl"); |
274 | exit(1); | 274 | exit(1); |
@@ -281,7 +281,7 @@ static void print_time(void) { | |||
281 | usleep(1000); | 281 | usleep(1000); |
282 | unsigned long long onems = getticks() - end_timestamp; | 282 | unsigned long long onems = getticks() - end_timestamp; |
283 | if (onems) { | 283 | if (onems) { |
284 | printf("Child process initialized in %.02f ms\n", | 284 | printf("Child process initialized in %.02f ms\n", |
285 | (float) (end_timestamp - start_timestamp) / (float) onems); | 285 | (float) (end_timestamp - start_timestamp) / (float) onems); |
286 | return; | 286 | return; |
287 | } | 287 | } |
@@ -301,7 +301,7 @@ void start_application(void) { | |||
301 | printf("starting application\n"); | 301 | printf("starting application\n"); |
302 | printf("LD_PRELOAD=%s\n", getenv("LD_PRELOAD")); | 302 | printf("LD_PRELOAD=%s\n", getenv("LD_PRELOAD")); |
303 | } | 303 | } |
304 | 304 | ||
305 | //**************************************** | 305 | //**************************************** |
306 | // audit | 306 | // audit |
307 | //**************************************** | 307 | //**************************************** |
@@ -405,12 +405,12 @@ static void enforce_filters(void) { | |||
405 | free(cfg.seccomp_list_keep); | 405 | free(cfg.seccomp_list_keep); |
406 | cfg.seccomp_list_keep = NULL; | 406 | cfg.seccomp_list_keep = NULL; |
407 | } | 407 | } |
408 | 408 | ||
409 | // disable all capabilities | 409 | // disable all capabilities |
410 | if (arg_caps_default_filter || arg_caps_list) | 410 | if (arg_caps_default_filter || arg_caps_list) |
411 | fwarning("all capabilities disabled for a regular user in chroot\n"); | 411 | fwarning("all capabilities disabled for a regular user in chroot\n"); |
412 | arg_caps_drop_all = 1; | 412 | arg_caps_drop_all = 1; |
413 | 413 | ||
414 | // drop all supplementary groups; /etc/group file inside chroot | 414 | // drop all supplementary groups; /etc/group file inside chroot |
415 | // is controlled by a regular usr | 415 | // is controlled by a regular usr |
416 | arg_nogroups = 1; | 416 | arg_nogroups = 1; |
@@ -424,12 +424,12 @@ int sandbox(void* sandbox_arg) { | |||
424 | 424 | ||
425 | pid_t child_pid = getpid(); | 425 | pid_t child_pid = getpid(); |
426 | if (arg_debug) | 426 | if (arg_debug) |
427 | printf("Initializing child process\n"); | 427 | printf("Initializing child process\n"); |
428 | 428 | ||
429 | // close each end of the unused pipes | 429 | // close each end of the unused pipes |
430 | close(parent_to_child_fds[1]); | 430 | close(parent_to_child_fds[1]); |
431 | close(child_to_parent_fds[0]); | 431 | close(child_to_parent_fds[0]); |
432 | 432 | ||
433 | // wait for parent to do base setup | 433 | // wait for parent to do base setup |
434 | wait_for_other(parent_to_child_fds[0]); | 434 | wait_for_other(parent_to_child_fds[0]); |
435 | 435 | ||
@@ -454,7 +454,7 @@ int sandbox(void* sandbox_arg) { | |||
454 | } | 454 | } |
455 | // ... and mount a tmpfs on top of /run/firejail/mnt directory | 455 | // ... and mount a tmpfs on top of /run/firejail/mnt directory |
456 | preproc_mount_mnt_dir(); | 456 | preproc_mount_mnt_dir(); |
457 | 457 | ||
458 | //**************************** | 458 | //**************************** |
459 | // log sandbox data | 459 | // log sandbox data |
460 | //**************************** | 460 | //**************************** |
@@ -463,12 +463,12 @@ int sandbox(void* sandbox_arg) { | |||
463 | fs_logger2int("sandbox pid:", (int) sandbox_pid); | 463 | fs_logger2int("sandbox pid:", (int) sandbox_pid); |
464 | if (cfg.chrootdir) | 464 | if (cfg.chrootdir) |
465 | fs_logger("sandbox filesystem: chroot"); | 465 | fs_logger("sandbox filesystem: chroot"); |
466 | else if (arg_overlay) | 466 | else if (arg_overlay) |
467 | fs_logger("sandbox filesystem: overlay"); | 467 | fs_logger("sandbox filesystem: overlay"); |
468 | else | 468 | else |
469 | fs_logger("sandbox filesystem: local"); | 469 | fs_logger("sandbox filesystem: local"); |
470 | fs_logger("install mount namespace"); | 470 | fs_logger("install mount namespace"); |
471 | 471 | ||
472 | //**************************** | 472 | //**************************** |
473 | // netfilter | 473 | // netfilter |
474 | //**************************** | 474 | //**************************** |
@@ -496,23 +496,23 @@ int sandbox(void* sandbox_arg) { | |||
496 | else if (any_bridge_configured() || any_interface_configured()) { | 496 | else if (any_bridge_configured() || any_interface_configured()) { |
497 | // configure lo and eth0...eth3 | 497 | // configure lo and eth0...eth3 |
498 | net_if_up("lo"); | 498 | net_if_up("lo"); |
499 | 499 | ||
500 | if (mac_not_zero(cfg.bridge0.macsandbox)) | 500 | if (mac_not_zero(cfg.bridge0.macsandbox)) |
501 | net_config_mac(cfg.bridge0.devsandbox, cfg.bridge0.macsandbox); | 501 | net_config_mac(cfg.bridge0.devsandbox, cfg.bridge0.macsandbox); |
502 | sandbox_if_up(&cfg.bridge0); | 502 | sandbox_if_up(&cfg.bridge0); |
503 | 503 | ||
504 | if (mac_not_zero(cfg.bridge1.macsandbox)) | 504 | if (mac_not_zero(cfg.bridge1.macsandbox)) |
505 | net_config_mac(cfg.bridge1.devsandbox, cfg.bridge1.macsandbox); | 505 | net_config_mac(cfg.bridge1.devsandbox, cfg.bridge1.macsandbox); |
506 | sandbox_if_up(&cfg.bridge1); | 506 | sandbox_if_up(&cfg.bridge1); |
507 | 507 | ||
508 | if (mac_not_zero(cfg.bridge2.macsandbox)) | 508 | if (mac_not_zero(cfg.bridge2.macsandbox)) |
509 | net_config_mac(cfg.bridge2.devsandbox, cfg.bridge2.macsandbox); | 509 | net_config_mac(cfg.bridge2.devsandbox, cfg.bridge2.macsandbox); |
510 | sandbox_if_up(&cfg.bridge2); | 510 | sandbox_if_up(&cfg.bridge2); |
511 | 511 | ||
512 | if (mac_not_zero(cfg.bridge3.macsandbox)) | 512 | if (mac_not_zero(cfg.bridge3.macsandbox)) |
513 | net_config_mac(cfg.bridge3.devsandbox, cfg.bridge3.macsandbox); | 513 | net_config_mac(cfg.bridge3.devsandbox, cfg.bridge3.macsandbox); |
514 | sandbox_if_up(&cfg.bridge3); | 514 | sandbox_if_up(&cfg.bridge3); |
515 | 515 | ||
516 | 516 | ||
517 | // moving an interface in a namespace using --interface will reset the interface configuration; | 517 | // moving an interface in a namespace using --interface will reset the interface configuration; |
518 | // we need to put the configuration back | 518 | // we need to put the configuration back |
@@ -520,23 +520,23 @@ int sandbox(void* sandbox_arg) { | |||
520 | if (arg_debug) | 520 | if (arg_debug) |
521 | printf("Configuring %d.%d.%d.%d address on interface %s\n", PRINT_IP(cfg.interface0.ip), cfg.interface0.dev); | 521 | printf("Configuring %d.%d.%d.%d address on interface %s\n", PRINT_IP(cfg.interface0.ip), cfg.interface0.dev); |
522 | net_config_interface(cfg.interface0.dev, cfg.interface0.ip, cfg.interface0.mask, cfg.interface0.mtu); | 522 | net_config_interface(cfg.interface0.dev, cfg.interface0.ip, cfg.interface0.mask, cfg.interface0.mtu); |
523 | } | 523 | } |
524 | if (cfg.interface1.configured && cfg.interface1.ip) { | 524 | if (cfg.interface1.configured && cfg.interface1.ip) { |
525 | if (arg_debug) | 525 | if (arg_debug) |
526 | printf("Configuring %d.%d.%d.%d address on interface %s\n", PRINT_IP(cfg.interface1.ip), cfg.interface1.dev); | 526 | printf("Configuring %d.%d.%d.%d address on interface %s\n", PRINT_IP(cfg.interface1.ip), cfg.interface1.dev); |
527 | net_config_interface(cfg.interface1.dev, cfg.interface1.ip, cfg.interface1.mask, cfg.interface1.mtu); | 527 | net_config_interface(cfg.interface1.dev, cfg.interface1.ip, cfg.interface1.mask, cfg.interface1.mtu); |
528 | } | 528 | } |
529 | if (cfg.interface2.configured && cfg.interface2.ip) { | 529 | if (cfg.interface2.configured && cfg.interface2.ip) { |
530 | if (arg_debug) | 530 | if (arg_debug) |
531 | printf("Configuring %d.%d.%d.%d address on interface %s\n", PRINT_IP(cfg.interface2.ip), cfg.interface2.dev); | 531 | printf("Configuring %d.%d.%d.%d address on interface %s\n", PRINT_IP(cfg.interface2.ip), cfg.interface2.dev); |
532 | net_config_interface(cfg.interface2.dev, cfg.interface2.ip, cfg.interface2.mask, cfg.interface2.mtu); | 532 | net_config_interface(cfg.interface2.dev, cfg.interface2.ip, cfg.interface2.mask, cfg.interface2.mtu); |
533 | } | 533 | } |
534 | if (cfg.interface3.configured && cfg.interface3.ip) { | 534 | if (cfg.interface3.configured && cfg.interface3.ip) { |
535 | if (arg_debug) | 535 | if (arg_debug) |
536 | printf("Configuring %d.%d.%d.%d address on interface %s\n", PRINT_IP(cfg.interface3.ip), cfg.interface3.dev); | 536 | printf("Configuring %d.%d.%d.%d address on interface %s\n", PRINT_IP(cfg.interface3.ip), cfg.interface3.dev); |
537 | net_config_interface(cfg.interface3.dev, cfg.interface3.ip, cfg.interface3.mask, cfg.interface3.mtu); | 537 | net_config_interface(cfg.interface3.dev, cfg.interface3.ip, cfg.interface3.mask, cfg.interface3.mtu); |
538 | } | 538 | } |
539 | 539 | ||
540 | // add a default route | 540 | // add a default route |
541 | if (cfg.defaultgw) { | 541 | if (cfg.defaultgw) { |
542 | // set the default route | 542 | // set the default route |
@@ -549,7 +549,7 @@ int sandbox(void* sandbox_arg) { | |||
549 | if (arg_debug) | 549 | if (arg_debug) |
550 | printf("Network namespace enabled\n"); | 550 | printf("Network namespace enabled\n"); |
551 | } | 551 | } |
552 | 552 | ||
553 | 553 | ||
554 | // print network configuration | 554 | // print network configuration |
555 | if (!arg_quiet) { | 555 | if (!arg_quiet) { |
@@ -561,7 +561,7 @@ int sandbox(void* sandbox_arg) { | |||
561 | sbox_run(SBOX_ROOT | SBOX_CAPS_NETWORK | SBOX_SECCOMP, 3, PATH_FNET, "printif", "scan"); | 561 | sbox_run(SBOX_ROOT | SBOX_CAPS_NETWORK | SBOX_SECCOMP, 3, PATH_FNET, "printif", "scan"); |
562 | else | 562 | else |
563 | sbox_run(SBOX_ROOT | SBOX_CAPS_NETWORK | SBOX_SECCOMP, 2, PATH_FNET, "printif", "scan"); | 563 | sbox_run(SBOX_ROOT | SBOX_CAPS_NETWORK | SBOX_SECCOMP, 2, PATH_FNET, "printif", "scan"); |
564 | 564 | ||
565 | } | 565 | } |
566 | if (cfg.defaultgw != 0) { | 566 | if (cfg.defaultgw != 0) { |
567 | if (gw_cfg_failed) | 567 | if (gw_cfg_failed) |
@@ -585,7 +585,7 @@ int sandbox(void* sandbox_arg) { | |||
585 | } | 585 | } |
586 | else | 586 | else |
587 | env_ibus_load(); | 587 | env_ibus_load(); |
588 | 588 | ||
589 | //**************************** | 589 | //**************************** |
590 | // fs pre-processing: | 590 | // fs pre-processing: |
591 | // - build seccomp filters | 591 | // - build seccomp filters |
@@ -602,7 +602,7 @@ int sandbox(void* sandbox_arg) { | |||
602 | if (rv) | 602 | if (rv) |
603 | exit(rv); | 603 | exit(rv); |
604 | } | 604 | } |
605 | #endif | 605 | #endif |
606 | 606 | ||
607 | // trace pre-install | 607 | // trace pre-install |
608 | if (arg_trace || arg_tracelog) | 608 | if (arg_trace || arg_tracelog) |
@@ -622,13 +622,13 @@ int sandbox(void* sandbox_arg) { | |||
622 | enforce_filters(); | 622 | enforce_filters(); |
623 | #ifdef HAVE_SECCOMP | 623 | #ifdef HAVE_SECCOMP |
624 | enforce_seccomp = 1; | 624 | enforce_seccomp = 1; |
625 | #endif | 625 | #endif |
626 | } | 626 | } |
627 | 627 | ||
628 | #ifdef HAVE_CHROOT | 628 | #ifdef HAVE_CHROOT |
629 | if (cfg.chrootdir) { | 629 | if (cfg.chrootdir) { |
630 | fs_chroot(cfg.chrootdir); | 630 | fs_chroot(cfg.chrootdir); |
631 | 631 | ||
632 | // force caps and seccomp if not started as root | 632 | // force caps and seccomp if not started as root |
633 | if (getuid() != 0) { | 633 | if (getuid() != 0) { |
634 | enforce_filters(); | 634 | enforce_filters(); |
@@ -638,14 +638,14 @@ int sandbox(void* sandbox_arg) { | |||
638 | } | 638 | } |
639 | else | 639 | else |
640 | arg_seccomp = 1; | 640 | arg_seccomp = 1; |
641 | 641 | ||
642 | //**************************** | 642 | //**************************** |
643 | // trace pre-install, this time inside chroot | 643 | // trace pre-install, this time inside chroot |
644 | //**************************** | 644 | //**************************** |
645 | if (arg_trace || arg_tracelog) | 645 | if (arg_trace || arg_tracelog) |
646 | fs_trace_preload(); | 646 | fs_trace_preload(); |
647 | } | 647 | } |
648 | else | 648 | else |
649 | #endif | 649 | #endif |
650 | #ifdef HAVE_OVERLAYFS | 650 | #ifdef HAVE_OVERLAYFS |
651 | if (arg_overlay) { | 651 | if (arg_overlay) { |
@@ -663,7 +663,7 @@ int sandbox(void* sandbox_arg) { | |||
663 | else | 663 | else |
664 | #endif | 664 | #endif |
665 | fs_basic_fs(); | 665 | fs_basic_fs(); |
666 | 666 | ||
667 | //**************************** | 667 | //**************************** |
668 | // private mode | 668 | // private mode |
669 | //**************************** | 669 | //**************************** |
@@ -696,7 +696,7 @@ int sandbox(void* sandbox_arg) { | |||
696 | else | 696 | else |
697 | fs_private_dev(); | 697 | fs_private_dev(); |
698 | } | 698 | } |
699 | 699 | ||
700 | if (arg_private_etc) { | 700 | if (arg_private_etc) { |
701 | if (cfg.chrootdir) | 701 | if (cfg.chrootdir) |
702 | fwarning("private-etc feature is disabled in chroot\n"); | 702 | fwarning("private-etc feature is disabled in chroot\n"); |
@@ -709,7 +709,7 @@ int sandbox(void* sandbox_arg) { | |||
709 | fs_trace_preload(); | 709 | fs_trace_preload(); |
710 | } | 710 | } |
711 | } | 711 | } |
712 | 712 | ||
713 | if (arg_private_opt) { | 713 | if (arg_private_opt) { |
714 | if (cfg.chrootdir) | 714 | if (cfg.chrootdir) |
715 | fwarning("private-opt feature is disabled in chroot\n"); | 715 | fwarning("private-opt feature is disabled in chroot\n"); |
@@ -719,7 +719,7 @@ int sandbox(void* sandbox_arg) { | |||
719 | fs_private_dir_list("/opt", RUN_OPT_DIR, cfg.opt_private_keep); | 719 | fs_private_dir_list("/opt", RUN_OPT_DIR, cfg.opt_private_keep); |
720 | } | 720 | } |
721 | } | 721 | } |
722 | 722 | ||
723 | if (arg_private_srv) { | 723 | if (arg_private_srv) { |
724 | if (cfg.chrootdir) | 724 | if (cfg.chrootdir) |
725 | fwarning("private-srv feature is disabled in chroot\n"); | 725 | fwarning("private-srv feature is disabled in chroot\n"); |
@@ -729,7 +729,7 @@ int sandbox(void* sandbox_arg) { | |||
729 | fs_private_dir_list("/srv", RUN_SRV_DIR, cfg.srv_private_keep); | 729 | fs_private_dir_list("/srv", RUN_SRV_DIR, cfg.srv_private_keep); |
730 | } | 730 | } |
731 | } | 731 | } |
732 | 732 | ||
733 | if (arg_private_bin) { | 733 | if (arg_private_bin) { |
734 | if (cfg.chrootdir) | 734 | if (cfg.chrootdir) |
735 | fwarning("private-bin feature is disabled in chroot\n"); | 735 | fwarning("private-bin feature is disabled in chroot\n"); |
@@ -748,7 +748,7 @@ int sandbox(void* sandbox_arg) { | |||
748 | fs_private_bin_list(); | 748 | fs_private_bin_list(); |
749 | } | 749 | } |
750 | } | 750 | } |
751 | 751 | ||
752 | if (arg_private_tmp) { | 752 | if (arg_private_tmp) { |
753 | if (cfg.chrootdir) | 753 | if (cfg.chrootdir) |
754 | fwarning("private-tmp feature is disabled in chroot\n"); | 754 | fwarning("private-tmp feature is disabled in chroot\n"); |
@@ -762,7 +762,7 @@ int sandbox(void* sandbox_arg) { | |||
762 | } | 762 | } |
763 | } | 763 | } |
764 | 764 | ||
765 | 765 | ||
766 | //**************************** | 766 | //**************************** |
767 | // hosts and hostname | 767 | // hosts and hostname |
768 | //**************************** | 768 | //**************************** |
@@ -777,19 +777,19 @@ int sandbox(void* sandbox_arg) { | |||
777 | //**************************** | 777 | //**************************** |
778 | if (arg_netns) | 778 | if (arg_netns) |
779 | netns_mounts(arg_netns); | 779 | netns_mounts(arg_netns); |
780 | 780 | ||
781 | //**************************** | 781 | //**************************** |
782 | // update /proc, /sys, /dev, /boot directory | 782 | // update /proc, /sys, /dev, /boot directory |
783 | //**************************** | 783 | //**************************** |
784 | if (checkcfg(CFG_REMOUNT_PROC_SYS)) | 784 | if (checkcfg(CFG_REMOUNT_PROC_SYS)) |
785 | fs_proc_sys_dev_boot(); | 785 | fs_proc_sys_dev_boot(); |
786 | 786 | ||
787 | //**************************** | 787 | //**************************** |
788 | // handle /mnt and /media | 788 | // handle /mnt and /media |
789 | //**************************** | 789 | //**************************** |
790 | if (checkcfg(CFG_DISABLE_MNT)) | 790 | if (checkcfg(CFG_DISABLE_MNT)) |
791 | fs_mnt(); | 791 | fs_mnt(); |
792 | 792 | ||
793 | //**************************** | 793 | //**************************** |
794 | // nosound/no3d and fix for pulseaudio 7.0 | 794 | // nosound/no3d and fix for pulseaudio 7.0 |
795 | //**************************** | 795 | //**************************** |
@@ -802,35 +802,43 @@ int sandbox(void* sandbox_arg) { | |||
802 | } | 802 | } |
803 | else | 803 | else |
804 | pulseaudio_init(); | 804 | pulseaudio_init(); |
805 | 805 | ||
806 | if (arg_no3d) | 806 | if (arg_no3d) |
807 | fs_dev_disable_3d(); | 807 | fs_dev_disable_3d(); |
808 | 808 | ||
809 | //**************************** | ||
810 | // novideo | ||
811 | //**************************** | ||
812 | if (arg_novideo) { | ||
813 | // disable /dev/video* | ||
814 | fs_dev_disable_video(); | ||
815 | } | ||
816 | |||
809 | //**************************** | 817 | //**************************** |
810 | // apply the profile file | 818 | // apply the profile file |
811 | //**************************** | 819 | //**************************** |
812 | // apply all whitelist commands ... | 820 | // apply all whitelist commands ... |
813 | if (cfg.chrootdir) | 821 | if (cfg.chrootdir) |
814 | fwarning("whitelist feature is disabled in chroot\n"); | 822 | fwarning("whitelist feature is disabled in chroot\n"); |
815 | else if (arg_overlay) | 823 | else if (arg_overlay) |
816 | fwarning("whitelist feature is disabled in overlay\n"); | 824 | fwarning("whitelist feature is disabled in overlay\n"); |
817 | else | 825 | else |
818 | fs_whitelist(); | 826 | fs_whitelist(); |
819 | 827 | ||
820 | // ... followed by blacklist commands | 828 | // ... followed by blacklist commands |
821 | fs_blacklist(); // mkdir and mkfile are processed all over again | 829 | fs_blacklist(); // mkdir and mkfile are processed all over again |
822 | 830 | ||
823 | //**************************** | 831 | //**************************** |
824 | // install trace | 832 | // install trace |
825 | //**************************** | 833 | //**************************** |
826 | if (arg_trace || arg_tracelog) | 834 | if (arg_trace || arg_tracelog) |
827 | fs_trace(); | 835 | fs_trace(); |
828 | 836 | ||
829 | //**************************** | 837 | //**************************** |
830 | // set dns | 838 | // set dns |
831 | //**************************** | 839 | //**************************** |
832 | fs_resolvconf(); | 840 | fs_resolvconf(); |
833 | 841 | ||
834 | //**************************** | 842 | //**************************** |
835 | // fs post-processing | 843 | // fs post-processing |
836 | //**************************** | 844 | //**************************** |
@@ -846,7 +854,7 @@ int sandbox(void* sandbox_arg) { | |||
846 | if (chdir(cfg.cwd) == 0) | 854 | if (chdir(cfg.cwd) == 0) |
847 | cwd = 1; | 855 | cwd = 1; |
848 | } | 856 | } |
849 | 857 | ||
850 | if (!cwd) { | 858 | if (!cwd) { |
851 | if (chdir("/") < 0) | 859 | if (chdir("/") < 0) |
852 | errExit("chdir"); | 860 | errExit("chdir"); |
@@ -866,8 +874,8 @@ int sandbox(void* sandbox_arg) { | |||
866 | free(cpath); | 874 | free(cpath); |
867 | } | 875 | } |
868 | } | 876 | } |
869 | 877 | ||
870 | 878 | ||
871 | // set nice | 879 | // set nice |
872 | if (arg_nice) { | 880 | if (arg_nice) { |
873 | errno = 0; | 881 | errno = 0; |
@@ -878,12 +886,12 @@ int sandbox(void* sandbox_arg) { | |||
878 | errno = 0; | 886 | errno = 0; |
879 | } | 887 | } |
880 | } | 888 | } |
881 | 889 | ||
882 | // clean /tmp/.X11-unix sockets | 890 | // clean /tmp/.X11-unix sockets |
883 | fs_x11(); | 891 | fs_x11(); |
884 | if (arg_x11_xorg) | 892 | if (arg_x11_xorg) |
885 | x11_xorg(); | 893 | x11_xorg(); |
886 | 894 | ||
887 | //**************************** | 895 | //**************************** |
888 | // set security filters | 896 | // set security filters |
889 | //**************************** | 897 | //**************************** |
@@ -899,7 +907,7 @@ int sandbox(void* sandbox_arg) { | |||
899 | save_cpu(); // save cpu affinity mask to CPU_CFG file | 907 | save_cpu(); // save cpu affinity mask to CPU_CFG file |
900 | set_cpu_affinity(); | 908 | set_cpu_affinity(); |
901 | } | 909 | } |
902 | 910 | ||
903 | // save cgroup in CGROUP_CFG file | 911 | // save cgroup in CGROUP_CFG file |
904 | if (cfg.cgroup) | 912 | if (cfg.cgroup) |
905 | save_cgroup(); | 913 | save_cgroup(); |
@@ -911,7 +919,7 @@ int sandbox(void* sandbox_arg) { | |||
911 | if (cfg.protocol) { | 919 | if (cfg.protocol) { |
912 | if (arg_debug) | 920 | if (arg_debug) |
913 | printf("Install protocol filter: %s\n", cfg.protocol); | 921 | printf("Install protocol filter: %s\n", cfg.protocol); |
914 | seccomp_load(RUN_SECCOMP_PROTOCOL); // install filter | 922 | seccomp_load(RUN_SECCOMP_PROTOCOL); // install filter |
915 | protocol_filter_save(); // save filter in RUN_PROTOCOL_CFG | 923 | protocol_filter_save(); // save filter in RUN_PROTOCOL_CFG |
916 | } | 924 | } |
917 | #endif | 925 | #endif |
@@ -939,12 +947,12 @@ int sandbox(void* sandbox_arg) { | |||
939 | } | 947 | } |
940 | else | 948 | else |
941 | drop_privs(arg_nogroups); | 949 | drop_privs(arg_nogroups); |
942 | 950 | ||
943 | // notify parent that new user namespace has been created so a proper | 951 | // notify parent that new user namespace has been created so a proper |
944 | // UID/GID map can be setup | 952 | // UID/GID map can be setup |
945 | notify_other(child_to_parent_fds[1]); | 953 | notify_other(child_to_parent_fds[1]); |
946 | close(child_to_parent_fds[1]); | 954 | close(child_to_parent_fds[1]); |
947 | 955 | ||
948 | // wait for parent to finish setting up a proper UID/GID map | 956 | // wait for parent to finish setting up a proper UID/GID map |
949 | wait_for_other(parent_to_child_fds[0]); | 957 | wait_for_other(parent_to_child_fds[0]); |
950 | close(parent_to_child_fds[0]); | 958 | close(parent_to_child_fds[0]); |
@@ -956,7 +964,7 @@ int sandbox(void* sandbox_arg) { | |||
956 | printf("noroot user namespace installed\n"); | 964 | printf("noroot user namespace installed\n"); |
957 | set_caps(); | 965 | set_caps(); |
958 | } | 966 | } |
959 | 967 | ||
960 | //**************************************** | 968 | //**************************************** |
961 | // Set NO_NEW_PRIVS if desired | 969 | // Set NO_NEW_PRIVS if desired |
962 | //**************************************** | 970 | //**************************************** |
@@ -989,7 +997,7 @@ int sandbox(void* sandbox_arg) { | |||
989 | else if (arg_debug) | 997 | else if (arg_debug) |
990 | printf("AppArmor enabled\n"); | 998 | printf("AppArmor enabled\n"); |
991 | } | 999 | } |
992 | #endif | 1000 | #endif |
993 | prctl(PR_SET_PDEATHSIG, SIGKILL, 0, 0, 0); // kill the child in case the parent died | 1001 | prctl(PR_SET_PDEATHSIG, SIGKILL, 0, 0, 0); // kill the child in case the parent died |
994 | start_application(); // start app | 1002 | start_application(); // start app |
995 | } | 1003 | } |