aboutsummaryrefslogtreecommitdiffstats
path: root/src/firejail/fs.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/firejail/fs.c')
-rw-r--r--src/firejail/fs.c150
1 files changed, 75 insertions, 75 deletions
diff --git a/src/firejail/fs.c b/src/firejail/fs.c
index ac68e7738..c60322dda 100644
--- a/src/firejail/fs.c
+++ b/src/firejail/fs.c
@@ -55,7 +55,7 @@ static void disable_file(OPERATION op, const char *filename) {
55 assert(filename); 55 assert(filename);
56 assert(op <OPERATION_MAX); 56 assert(op <OPERATION_MAX);
57 last_disable = UNSUCCESSFUL; 57 last_disable = UNSUCCESSFUL;
58 58
59 // Resolve all symlinks 59 // Resolve all symlinks
60 char* fname = realpath(filename, NULL); 60 char* fname = realpath(filename, NULL);
61 if (fname == NULL && errno != EACCES) { 61 if (fname == NULL && errno != EACCES) {
@@ -87,10 +87,10 @@ static void disable_file(OPERATION op, const char *filename) {
87 if (arg_debug) 87 if (arg_debug)
88 printf("Warning (blacklisting): %s is an invalid file, skipping...\n", filename); 88 printf("Warning (blacklisting): %s is an invalid file, skipping...\n", filename);
89 } 89 }
90 90
91 return; 91 return;
92 } 92 }
93 93
94 // if the file is not present, do nothing 94 // if the file is not present, do nothing
95 struct stat s; 95 struct stat s;
96 if (fname == NULL) 96 if (fname == NULL)
@@ -124,7 +124,7 @@ static void disable_file(OPERATION op, const char *filename) {
124 else 124 else
125 printf(" - no logging\n"); 125 printf(" - no logging\n");
126 } 126 }
127 127
128 if (S_ISDIR(s.st_mode)) { 128 if (S_ISDIR(s.st_mode)) {
129 if (mount(RUN_RO_DIR, fname, "none", MS_BIND, "mode=400,gid=0") < 0) 129 if (mount(RUN_RO_DIR, fname, "none", MS_BIND, "mode=400,gid=0") < 0)
130 errExit("disable file"); 130 errExit("disable file");
@@ -243,7 +243,7 @@ void fs_blacklist(void) {
243 ProfileEntry *entry = cfg.profile; 243 ProfileEntry *entry = cfg.profile;
244 if (!entry) 244 if (!entry)
245 return; 245 return;
246 246
247 size_t noblacklist_c = 0; 247 size_t noblacklist_c = 0;
248 size_t noblacklist_m = 32; 248 size_t noblacklist_m = 32;
249 char **noblacklist = calloc(noblacklist_m, sizeof(*noblacklist)); 249 char **noblacklist = calloc(noblacklist_m, sizeof(*noblacklist));
@@ -256,7 +256,7 @@ void fs_blacklist(void) {
256 char *ptr; 256 char *ptr;
257 257
258 // whitelist commands handled by fs_whitelist() 258 // whitelist commands handled by fs_whitelist()
259 if (strncmp(entry->data, "whitelist ", 10) == 0 || 259 if (strncmp(entry->data, "whitelist ", 10) == 0 ||
260 strncmp(entry->data, "nowhitelist ", 12) == 0 || 260 strncmp(entry->data, "nowhitelist ", 12) == 0 ||
261 *entry->data == '\0') { 261 *entry->data == '\0') {
262 entry = entry->next; 262 entry = entry->next;
@@ -275,7 +275,7 @@ void fs_blacklist(void) {
275 entry = entry->next; 275 entry = entry->next;
276 continue; 276 continue;
277 } 277 }
278 278
279 // mount --bind olddir newdir 279 // mount --bind olddir newdir
280 if (arg_debug) 280 if (arg_debug)
281 printf("Mount-bind %s on top of %s\n", dname1, dname2); 281 printf("Mount-bind %s on top of %s\n", dname1, dname2);
@@ -284,8 +284,8 @@ void fs_blacklist(void) {
284 errExit("mount bind"); 284 errExit("mount bind");
285 /* coverity[toctou] */ 285 /* coverity[toctou] */
286 if (set_perms(dname2, s.st_uid, s.st_gid,s.st_mode)) 286 if (set_perms(dname2, s.st_uid, s.st_gid,s.st_mode))
287 errExit("set_perms"); 287 errExit("set_perms");
288 288
289 entry = entry->next; 289 entry = entry->next;
290 continue; 290 continue;
291 } 291 }
@@ -348,33 +348,33 @@ void fs_blacklist(void) {
348 else if (strncmp(entry->data, "read-only ", 10) == 0) { 348 else if (strncmp(entry->data, "read-only ", 10) == 0) {
349 ptr = entry->data + 10; 349 ptr = entry->data + 10;
350 op = MOUNT_READONLY; 350 op = MOUNT_READONLY;
351 } 351 }
352 else if (strncmp(entry->data, "read-write ", 11) == 0) { 352 else if (strncmp(entry->data, "read-write ", 11) == 0) {
353 ptr = entry->data + 11; 353 ptr = entry->data + 11;
354 op = MOUNT_RDWR; 354 op = MOUNT_RDWR;
355 } 355 }
356 else if (strncmp(entry->data, "noexec ", 7) == 0) { 356 else if (strncmp(entry->data, "noexec ", 7) == 0) {
357 ptr = entry->data + 7; 357 ptr = entry->data + 7;
358 op = MOUNT_NOEXEC; 358 op = MOUNT_NOEXEC;
359 } 359 }
360 else if (strncmp(entry->data, "tmpfs ", 6) == 0) { 360 else if (strncmp(entry->data, "tmpfs ", 6) == 0) {
361 ptr = entry->data + 6; 361 ptr = entry->data + 6;
362 op = MOUNT_TMPFS; 362 op = MOUNT_TMPFS;
363 } 363 }
364 else if (strncmp(entry->data, "mkdir ", 6) == 0) { 364 else if (strncmp(entry->data, "mkdir ", 6) == 0) {
365 EUID_USER(); 365 EUID_USER();
366 fs_mkdir(entry->data + 6); 366 fs_mkdir(entry->data + 6);
367 EUID_ROOT(); 367 EUID_ROOT();
368 entry = entry->next; 368 entry = entry->next;
369 continue; 369 continue;
370 } 370 }
371 else if (strncmp(entry->data, "mkfile ", 7) == 0) { 371 else if (strncmp(entry->data, "mkfile ", 7) == 0) {
372 EUID_USER(); 372 EUID_USER();
373 fs_mkfile(entry->data + 7); 373 fs_mkfile(entry->data + 7);
374 EUID_ROOT(); 374 EUID_ROOT();
375 entry = entry->next; 375 entry = entry->next;
376 continue; 376 continue;
377 } 377 }
378 else { 378 else {
379 fprintf(stderr, "Error: invalid profile line %s\n", entry->data); 379 fprintf(stderr, "Error: invalid profile line %s\n", entry->data);
380 entry = entry->next; 380 entry = entry->next;
@@ -446,10 +446,10 @@ static void fs_rdwr(const char *dir) {
446 fwarning("you are not allowed to change %s to read-write\n", dir); 446 fwarning("you are not allowed to change %s to read-write\n", dir);
447 return; 447 return;
448 } 448 }
449 449
450 // mount --bind /bin /bin 450 // mount --bind /bin /bin
451 // mount --bind -o remount,rw /bin 451 // mount --bind -o remount,rw /bin
452 if (mount(dir, dir, NULL, MS_BIND|MS_REC, NULL) < 0 || 452 if (mount(dir, dir, NULL, MS_BIND|MS_REC, NULL) < 0 ||
453 mount(NULL, dir, NULL, MS_BIND|MS_REMOUNT|MS_REC, NULL) < 0) 453 mount(NULL, dir, NULL, MS_BIND|MS_REMOUNT|MS_REC, NULL) < 0)
454 errExit("mount read-write"); 454 errExit("mount read-write");
455 fs_logger2("read-write", dir); 455 fs_logger2("read-write", dir);
@@ -464,7 +464,7 @@ void fs_noexec(const char *dir) {
464 if (rv == 0) { 464 if (rv == 0) {
465 // mount --bind /bin /bin 465 // mount --bind /bin /bin
466 // mount --bind -o remount,ro /bin 466 // mount --bind -o remount,ro /bin
467 if (mount(dir, dir, NULL, MS_BIND|MS_REC, NULL) < 0 || 467 if (mount(dir, dir, NULL, MS_BIND|MS_REC, NULL) < 0 ||
468 mount(NULL, dir, NULL, MS_BIND|MS_REMOUNT|MS_NOEXEC|MS_NODEV|MS_NOSUID|MS_REC, NULL) < 0) 468 mount(NULL, dir, NULL, MS_BIND|MS_REMOUNT|MS_NOEXEC|MS_NODEV|MS_NOSUID|MS_REC, NULL) < 0)
469 errExit("mount noexec"); 469 errExit("mount noexec");
470 fs_logger2("noexec", dir); 470 fs_logger2("noexec", dir);
@@ -504,11 +504,11 @@ void fs_proc_sys_dev_boot(void) {
504 fwarning("failed to mount /sys\n"); 504 fwarning("failed to mount /sys\n");
505 else 505 else
506 fs_logger("remount /sys"); 506 fs_logger("remount /sys");
507 507
508 disable_file(BLACKLIST_FILE, "/sys/firmware"); 508 disable_file(BLACKLIST_FILE, "/sys/firmware");
509 disable_file(BLACKLIST_FILE, "/sys/hypervisor"); 509 disable_file(BLACKLIST_FILE, "/sys/hypervisor");
510 { // allow user access to /sys/fs if "--noblacklist=/sys/fs" is present on the command line 510 { // allow user access to /sys/fs if "--noblacklist=/sys/fs" is present on the command line
511 EUID_USER(); 511 EUID_USER();
512 profile_add("blacklist /sys/fs"); 512 profile_add("blacklist /sys/fs");
513 EUID_ROOT(); 513 EUID_ROOT();
514 } 514 }
@@ -519,11 +519,11 @@ void fs_proc_sys_dev_boot(void) {
519 disable_file(BLACKLIST_FILE, "/sys/kernel/uevent_helper"); 519 disable_file(BLACKLIST_FILE, "/sys/kernel/uevent_helper");
520 520
521 // various /proc/sys files 521 // various /proc/sys files
522 disable_file(BLACKLIST_FILE, "/proc/sys/security"); 522 disable_file(BLACKLIST_FILE, "/proc/sys/security");
523 disable_file(BLACKLIST_FILE, "/proc/sys/efi/vars"); 523 disable_file(BLACKLIST_FILE, "/proc/sys/efi/vars");
524 disable_file(BLACKLIST_FILE, "/proc/sys/fs/binfmt_misc"); 524 disable_file(BLACKLIST_FILE, "/proc/sys/fs/binfmt_misc");
525 disable_file(BLACKLIST_FILE, "/proc/sys/kernel/core_pattern"); 525 disable_file(BLACKLIST_FILE, "/proc/sys/kernel/core_pattern");
526 disable_file(BLACKLIST_FILE, "/proc/sys/kernel/modprobe"); 526 disable_file(BLACKLIST_FILE, "/proc/sys/kernel/modprobe");
527 disable_file(BLACKLIST_FILE, "/proc/sysrq-trigger"); 527 disable_file(BLACKLIST_FILE, "/proc/sysrq-trigger");
528 disable_file(BLACKLIST_FILE, "/proc/sys/kernel/hotplug"); 528 disable_file(BLACKLIST_FILE, "/proc/sys/kernel/hotplug");
529 disable_file(BLACKLIST_FILE, "/proc/sys/vm/panic_on_oom"); 529 disable_file(BLACKLIST_FILE, "/proc/sys/vm/panic_on_oom");
@@ -531,15 +531,15 @@ void fs_proc_sys_dev_boot(void) {
531 // various /proc files 531 // various /proc files
532 disable_file(BLACKLIST_FILE, "/proc/irq"); 532 disable_file(BLACKLIST_FILE, "/proc/irq");
533 disable_file(BLACKLIST_FILE, "/proc/bus"); 533 disable_file(BLACKLIST_FILE, "/proc/bus");
534 disable_file(BLACKLIST_FILE, "/proc/config.gz"); 534 disable_file(BLACKLIST_FILE, "/proc/config.gz");
535 disable_file(BLACKLIST_FILE, "/proc/sched_debug"); 535 disable_file(BLACKLIST_FILE, "/proc/sched_debug");
536 disable_file(BLACKLIST_FILE, "/proc/timer_list"); 536 disable_file(BLACKLIST_FILE, "/proc/timer_list");
537 disable_file(BLACKLIST_FILE, "/proc/timer_stats"); 537 disable_file(BLACKLIST_FILE, "/proc/timer_stats");
538 disable_file(BLACKLIST_FILE, "/proc/kcore"); 538 disable_file(BLACKLIST_FILE, "/proc/kcore");
539 disable_file(BLACKLIST_FILE, "/proc/kallsyms"); 539 disable_file(BLACKLIST_FILE, "/proc/kallsyms");
540 disable_file(BLACKLIST_FILE, "/proc/mem"); 540 disable_file(BLACKLIST_FILE, "/proc/mem");
541 disable_file(BLACKLIST_FILE, "/proc/kmem"); 541 disable_file(BLACKLIST_FILE, "/proc/kmem");
542 542
543 // remove kernel symbol information 543 // remove kernel symbol information
544 if (!arg_allow_debuggers) { 544 if (!arg_allow_debuggers) {
545 disable_file(BLACKLIST_FILE, "/usr/src/linux"); 545 disable_file(BLACKLIST_FILE, "/usr/src/linux");
@@ -547,18 +547,18 @@ void fs_proc_sys_dev_boot(void) {
547 disable_file(BLACKLIST_FILE, "/usr/lib/debug"); 547 disable_file(BLACKLIST_FILE, "/usr/lib/debug");
548 disable_file(BLACKLIST_FILE, "/boot"); 548 disable_file(BLACKLIST_FILE, "/boot");
549 } 549 }
550 550
551 // disable /selinux 551 // disable /selinux
552 disable_file(BLACKLIST_FILE, "/selinux"); 552 disable_file(BLACKLIST_FILE, "/selinux");
553 553
554 // disable /dev/port 554 // disable /dev/port
555 disable_file(BLACKLIST_FILE, "/dev/port"); 555 disable_file(BLACKLIST_FILE, "/dev/port");
556 556
557 557
558 558
559 // disable various ipc sockets in /run/user 559 // disable various ipc sockets in /run/user
560 struct stat s; 560 struct stat s;
561 561
562 char *fname; 562 char *fname;
563 if (asprintf(&fname, "/run/usr/%d", getuid()) == -1) 563 if (asprintf(&fname, "/run/usr/%d", getuid()) == -1)
564 errExit("asprintf"); 564 errExit("asprintf");
@@ -567,24 +567,24 @@ void fs_proc_sys_dev_boot(void) {
567 char *fnamegpg; 567 char *fnamegpg;
568 if (asprintf(&fnamegpg, "/run/user/%d/gnupg", getuid()) == -1) 568 if (asprintf(&fnamegpg, "/run/user/%d/gnupg", getuid()) == -1)
569 errExit("asprintf"); 569 errExit("asprintf");
570 if (stat(fnamegpg, &s) == -1) 570 if (stat(fnamegpg, &s) == -1)
571 mkdir_attr(fnamegpg, 0700, getuid(), getgid()); 571 mkdir_attr(fnamegpg, 0700, getuid(), getgid());
572 if (stat(fnamegpg, &s) == 0) 572 if (stat(fnamegpg, &s) == 0)
573 disable_file(BLACKLIST_FILE, fnamegpg); 573 disable_file(BLACKLIST_FILE, fnamegpg);
574 free(fnamegpg); 574 free(fnamegpg);
575 575
576 // disable /run/user/{uid}/systemd 576 // disable /run/user/{uid}/systemd
577 char *fnamesysd; 577 char *fnamesysd;
578 if (asprintf(&fnamesysd, "/run/user/%d/systemd", getuid()) == -1) 578 if (asprintf(&fnamesysd, "/run/user/%d/systemd", getuid()) == -1)
579 errExit("asprintf"); 579 errExit("asprintf");
580 if (stat(fnamesysd, &s) == -1) 580 if (stat(fnamesysd, &s) == -1)
581 mkdir_attr(fnamesysd, 0755, getuid(), getgid()); 581 mkdir_attr(fnamesysd, 0755, getuid(), getgid());
582 if (stat(fnamesysd, &s) == 0) 582 if (stat(fnamesysd, &s) == 0)
583 disable_file(BLACKLIST_FILE, fnamesysd); 583 disable_file(BLACKLIST_FILE, fnamesysd);
584 free(fnamesysd); 584 free(fnamesysd);
585 } 585 }
586 free(fname); 586 free(fname);
587 587
588 if (getuid() != 0) { 588 if (getuid() != 0) {
589 // disable /dev/kmsg and /proc/kmsg 589 // disable /dev/kmsg and /proc/kmsg
590 disable_file(BLACKLIST_FILE, "/dev/kmsg"); 590 disable_file(BLACKLIST_FILE, "/dev/kmsg");
@@ -602,7 +602,7 @@ static void disable_config(void) {
602 if (stat(fname, &s) == 0) 602 if (stat(fname, &s) == 0)
603 disable_file(BLACKLIST_FILE, fname); 603 disable_file(BLACKLIST_FILE, fname);
604 free(fname); 604 free(fname);
605 605
606 // disable run time information 606 // disable run time information
607 if (stat(RUN_FIREJAIL_NETWORK_DIR, &s) == 0) 607 if (stat(RUN_FIREJAIL_NETWORK_DIR, &s) == 0)
608 disable_file(BLACKLIST_FILE, RUN_FIREJAIL_NETWORK_DIR); 608 disable_file(BLACKLIST_FILE, RUN_FIREJAIL_NETWORK_DIR);
@@ -618,7 +618,7 @@ static void disable_config(void) {
618// build a basic read-only filesystem 618// build a basic read-only filesystem
619void fs_basic_fs(void) { 619void fs_basic_fs(void) {
620 uid_t uid = getuid(); 620 uid_t uid = getuid();
621 621
622 if (arg_debug) 622 if (arg_debug)
623 printf("Mounting read-only /bin, /sbin, /lib, /lib32, /lib64, /usr"); 623 printf("Mounting read-only /bin, /sbin, /lib, /lib32, /lib64, /usr");
624 if (!arg_writable_etc) { 624 if (!arg_writable_etc) {
@@ -649,15 +649,15 @@ void fs_basic_fs(void) {
649 fs_var_log(); 649 fs_var_log();
650 else 650 else
651 fs_rdwr("/var/log"); 651 fs_rdwr("/var/log");
652 652
653 fs_var_lib(); 653 fs_var_lib();
654 fs_var_cache(); 654 fs_var_cache();
655 fs_var_utmp(); 655 fs_var_utmp();
656 fs_machineid(); 656 fs_machineid();
657 657
658 // don't leak user information 658 // don't leak user information
659 restrict_users(); 659 restrict_users();
660 660
661 // when starting as root, firejail config is not disabled; 661 // when starting as root, firejail config is not disabled;
662 // this mode could be used to install and test new software by chaining 662 // this mode could be used to install and test new software by chaining
663 // firejail sandboxes (firejail --force) 663 // firejail sandboxes (firejail --force)
@@ -675,7 +675,7 @@ char *fs_check_overlay_dir(const char *subdirname, int allow_reuse) {
675 // create ~/.firejail directory 675 // create ~/.firejail directory
676 if (asprintf(&dirname, "%s/.firejail", cfg.homedir) == -1) 676 if (asprintf(&dirname, "%s/.firejail", cfg.homedir) == -1)
677 errExit("asprintf"); 677 errExit("asprintf");
678 678
679 if (is_link(dirname)) { 679 if (is_link(dirname)) {
680 fprintf(stderr, "Error: invalid ~/.firejail directory\n"); 680 fprintf(stderr, "Error: invalid ~/.firejail directory\n");
681 exit(1); 681 exit(1);
@@ -688,7 +688,7 @@ char *fs_check_overlay_dir(const char *subdirname, int allow_reuse) {
688 if (child == 0) { 688 if (child == 0) {
689 // drop privileges 689 // drop privileges
690 drop_privs(0); 690 drop_privs(0);
691 691
692 // create directory 692 // create directory
693 if (mkdir(dirname, 0700)) 693 if (mkdir(dirname, 0700))
694 errExit("mkdir"); 694 errExit("mkdir");
@@ -770,7 +770,7 @@ void fs_overlayfs(void) {
770 fprintf(stderr, "Error: cannot extract Linux kernel version: %s\n", u.version); 770 fprintf(stderr, "Error: cannot extract Linux kernel version: %s\n", u.version);
771 exit(1); 771 exit(1);
772 } 772 }
773 773
774 if (arg_debug) 774 if (arg_debug)
775 printf("Linux kernel version %d.%d\n", major, minor); 775 printf("Linux kernel version %d.%d\n", major, minor);
776 int oldkernel = 0; 776 int oldkernel = 0;
@@ -780,7 +780,7 @@ void fs_overlayfs(void) {
780 } 780 }
781 if (major == 3 && minor < 18) 781 if (major == 3 && minor < 18)
782 oldkernel = 1; 782 oldkernel = 1;
783 783
784 char *oroot; 784 char *oroot;
785 if(asprintf(&oroot, "%s/oroot", RUN_MNT_DIR) == -1) 785 if(asprintf(&oroot, "%s/oroot", RUN_MNT_DIR) == -1)
786 errExit("asprintf"); 786 errExit("asprintf");
@@ -818,7 +818,7 @@ void fs_overlayfs(void) {
818 } 818 }
819 else if (set_perms(odiff, 0, 0, 0755)) 819 else if (set_perms(odiff, 0, 0, 0755))
820 errExit("set_perms"); 820 errExit("set_perms");
821 821
822 char *owork; 822 char *owork;
823 if(asprintf(&owork, "%s/owork", basedir) == -1) 823 if(asprintf(&owork, "%s/owork", basedir) == -1)
824 errExit("asprintf"); 824 errExit("asprintf");
@@ -829,7 +829,7 @@ void fs_overlayfs(void) {
829 } 829 }
830 else if (set_perms(owork, 0, 0, 0755)) 830 else if (set_perms(owork, 0, 0, 0755))
831 errExit("chown"); 831 errExit("chown");
832 832
833 // mount overlayfs 833 // mount overlayfs
834 if (arg_debug) 834 if (arg_debug)
835 printf("Mounting OverlayFS\n"); 835 printf("Mounting OverlayFS\n");
@@ -849,11 +849,11 @@ void fs_overlayfs(void) {
849 errExit("asprintf"); 849 errExit("asprintf");
850 if (mount("overlay", oroot, "overlay", MS_MGC_VAL, option) < 0) 850 if (mount("overlay", oroot, "overlay", MS_MGC_VAL, option) < 0)
851 errExit("mounting overlayfs"); 851 errExit("mounting overlayfs");
852 852
853 //*************************** 853 //***************************
854 // issue #263 start code 854 // issue #263 start code
855 // My setup has a separate mount point for /home. When the overlay is mounted, 855 // My setup has a separate mount point for /home. When the overlay is mounted,
856 // the overlay does not contain the original /home contents. 856 // the overlay does not contain the original /home contents.
857 // I added code to create a second overlay for /home if the overlay home dir is empty and this seems to work 857 // I added code to create a second overlay for /home if the overlay home dir is empty and this seems to work
858 // @dshmgh, Jan 2016 858 // @dshmgh, Jan 2016
859 { 859 {
@@ -862,22 +862,22 @@ void fs_overlayfs(void) {
862 char *hroot; 862 char *hroot;
863 char *hdiff; 863 char *hdiff;
864 char *hwork; 864 char *hwork;
865 865
866 // dons add debug 866 // dons add debug
867 if (arg_debug) printf ("DEBUG: chroot dirs are oroot %s odiff %s owork %s\n",oroot,odiff,owork); 867 if (arg_debug) printf ("DEBUG: chroot dirs are oroot %s odiff %s owork %s\n",oroot,odiff,owork);
868 868
869 // BEFORE NEXT, WE NEED TO TEST IF /home has any contents or do we need to mount it? 869 // BEFORE NEXT, WE NEED TO TEST IF /home has any contents or do we need to mount it?
870 // must create var for oroot/cfg.homedir 870 // must create var for oroot/cfg.homedir
871 if (asprintf(&overlayhome,"%s%s",oroot,cfg.homedir) == -1) 871 if (asprintf(&overlayhome,"%s%s",oroot,cfg.homedir) == -1)
872 errExit("asprintf"); 872 errExit("asprintf");
873 if (arg_debug) printf ("DEBUG: overlayhome var holds ##%s##\n",overlayhome); 873 if (arg_debug) printf ("DEBUG: overlayhome var holds ##%s##\n",overlayhome);
874 874
875 // if no homedir in overlay -- create another overlay for /home 875 // if no homedir in overlay -- create another overlay for /home
876 if (stat(overlayhome, &s) == -1) { 876 if (stat(overlayhome, &s) == -1) {
877 877
878 if(asprintf(&hroot, "%s/oroot/home", RUN_MNT_DIR) == -1) 878 if(asprintf(&hroot, "%s/oroot/home", RUN_MNT_DIR) == -1)
879 errExit("asprintf"); 879 errExit("asprintf");
880 880
881 if(asprintf(&hdiff, "%s/hdiff", basedir) == -1) 881 if(asprintf(&hdiff, "%s/hdiff", basedir) == -1)
882 errExit("asprintf"); 882 errExit("asprintf");
883 883
@@ -887,7 +887,7 @@ void fs_overlayfs(void) {
887 } 887 }
888 else if (set_perms(hdiff, 0, 0, S_IRWXU | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH)) 888 else if (set_perms(hdiff, 0, 0, S_IRWXU | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH))
889 errExit("set_perms"); 889 errExit("set_perms");
890 890
891 if(asprintf(&hwork, "%s/hwork", basedir) == -1) 891 if(asprintf(&hwork, "%s/hwork", basedir) == -1)
892 errExit("asprintf"); 892 errExit("asprintf");
893 893
@@ -897,13 +897,13 @@ void fs_overlayfs(void) {
897 } 897 }
898 else if (set_perms(hwork, 0, 0, S_IRWXU | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH)) 898 else if (set_perms(hwork, 0, 0, S_IRWXU | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH))
899 errExit("set_perms"); 899 errExit("set_perms");
900 900
901 // no homedir in overlay so now mount another overlay for /home 901 // no homedir in overlay so now mount another overlay for /home
902 if (asprintf(&option, "lowerdir=/home,upperdir=%s,workdir=%s", hdiff, hwork) == -1) 902 if (asprintf(&option, "lowerdir=/home,upperdir=%s,workdir=%s", hdiff, hwork) == -1)
903 errExit("asprintf"); 903 errExit("asprintf");
904 if (mount("overlay", hroot, "overlay", MS_MGC_VAL, option) < 0) 904 if (mount("overlay", hroot, "overlay", MS_MGC_VAL, option) < 0)
905 errExit("mounting overlayfs for mounted home directory"); 905 errExit("mounting overlayfs for mounted home directory");
906 906
907 printf("OverlayFS for /home configured in %s directory\n", basedir); 907 printf("OverlayFS for /home configured in %s directory\n", basedir);
908 } // stat(overlayhome) 908 } // stat(overlayhome)
909 free(overlayhome); 909 free(overlayhome);
@@ -913,7 +913,7 @@ void fs_overlayfs(void) {
913 } 913 }
914 if (!arg_quiet) 914 if (!arg_quiet)
915 printf("OverlayFS configured in %s directory\n", basedir); 915 printf("OverlayFS configured in %s directory\n", basedir);
916 916
917 // mount-bind dev directory 917 // mount-bind dev directory
918 if (arg_debug) 918 if (arg_debug)
919 printf("Mounting /dev\n"); 919 printf("Mounting /dev\n");
@@ -964,7 +964,7 @@ void fs_overlayfs(void) {
964 fs_var_log(); 964 fs_var_log();
965 else 965 else
966 fs_rdwr("/var/log"); 966 fs_rdwr("/var/log");
967 967
968 fs_var_lib(); 968 fs_var_lib();
969 fs_var_cache(); 969 fs_var_cache();
970 fs_var_utmp(); 970 fs_var_utmp();
@@ -987,7 +987,7 @@ void fs_overlayfs(void) {
987#endif 987#endif
988 988
989 989
990#ifdef HAVE_CHROOT 990#ifdef HAVE_CHROOT
991// return 1 if error 991// return 1 if error
992void fs_check_chroot_dir(const char *rootdir) { 992void fs_check_chroot_dir(const char *rootdir) {
993 EUID_ASSERT(); 993 EUID_ASSERT();
@@ -1035,7 +1035,7 @@ void fs_check_chroot_dir(const char *rootdir) {
1035 exit(1); 1035 exit(1);
1036 } 1036 }
1037 free(name); 1037 free(name);
1038 1038
1039 // check /proc 1039 // check /proc
1040 if (asprintf(&name, "%s/proc", rootdir) == -1) 1040 if (asprintf(&name, "%s/proc", rootdir) == -1)
1041 errExit("asprintf"); 1041 errExit("asprintf");
@@ -1048,7 +1048,7 @@ void fs_check_chroot_dir(const char *rootdir) {
1048 exit(1); 1048 exit(1);
1049 } 1049 }
1050 free(name); 1050 free(name);
1051 1051
1052 // check /tmp 1052 // check /tmp
1053 if (asprintf(&name, "%s/tmp", rootdir) == -1) 1053 if (asprintf(&name, "%s/tmp", rootdir) == -1)
1054 errExit("asprintf"); 1054 errExit("asprintf");
@@ -1110,7 +1110,7 @@ void fs_check_chroot_dir(const char *rootdir) {
1110// chroot into an existing directory; mount exiting /dev and update /etc/resolv.conf 1110// chroot into an existing directory; mount exiting /dev and update /etc/resolv.conf
1111void fs_chroot(const char *rootdir) { 1111void fs_chroot(const char *rootdir) {
1112 assert(rootdir); 1112 assert(rootdir);
1113 1113
1114 if (checkcfg(CFG_CHROOT_DESKTOP)) { 1114 if (checkcfg(CFG_CHROOT_DESKTOP)) {
1115 // mount-bind a /dev in rootdir 1115 // mount-bind a /dev in rootdir
1116 char *newdev; 1116 char *newdev;
@@ -1121,7 +1121,7 @@ void fs_chroot(const char *rootdir) {
1121 if (mount("/dev", newdev, NULL, MS_BIND|MS_REC, NULL) < 0) 1121 if (mount("/dev", newdev, NULL, MS_BIND|MS_REC, NULL) < 0)
1122 errExit("mounting /dev"); 1122 errExit("mounting /dev");
1123 free(newdev); 1123 free(newdev);
1124 1124
1125 // x11 1125 // x11
1126 if (getenv("FIREJAIL_X11")) { 1126 if (getenv("FIREJAIL_X11")) {
1127 char *newx11; 1127 char *newx11;
@@ -1133,7 +1133,7 @@ void fs_chroot(const char *rootdir) {
1133 errExit("mounting /tmp/.X11-unix"); 1133 errExit("mounting /tmp/.X11-unix");
1134 free(newx11); 1134 free(newx11);
1135 } 1135 }
1136 1136
1137 // some older distros don't have a /run directory 1137 // some older distros don't have a /run directory
1138 // create one by default 1138 // create one by default
1139 // create /run/firejail directory in chroot 1139 // create /run/firejail directory in chroot
@@ -1150,7 +1150,7 @@ void fs_chroot(const char *rootdir) {
1150 errExit("asprintf"); 1150 errExit("asprintf");
1151 create_empty_dir_as_root(rundir, 0755); 1151 create_empty_dir_as_root(rundir, 0755);
1152 free(rundir); 1152 free(rundir);
1153 1153
1154 // create /run/firejail/mnt directory in chroot and mount the current one 1154 // create /run/firejail/mnt directory in chroot and mount the current one
1155 if (asprintf(&rundir, "%s%s", rootdir, RUN_MNT_DIR) == -1) 1155 if (asprintf(&rundir, "%s%s", rootdir, RUN_MNT_DIR) == -1)
1156 errExit("asprintf"); 1156 errExit("asprintf");
@@ -1173,7 +1173,7 @@ void fs_chroot(const char *rootdir) {
1173 if (copy_file("/etc/resolv.conf", fname, 0, 0, 0644) == -1) // root needed 1173 if (copy_file("/etc/resolv.conf", fname, 0, 0, 0644) == -1) // root needed
1174 fwarning("/etc/resolv.conf not initialized\n"); 1174 fwarning("/etc/resolv.conf not initialized\n");
1175 } 1175 }
1176 1176
1177 // chroot into the new directory 1177 // chroot into the new directory
1178#ifdef HAVE_GCOV 1178#ifdef HAVE_GCOV
1179 __gcov_flush(); 1179 __gcov_flush();
@@ -1196,15 +1196,15 @@ void fs_chroot(const char *rootdir) {
1196 fs_var_log(); 1196 fs_var_log();
1197 else 1197 else
1198 fs_rdwr("/var/log"); 1198 fs_rdwr("/var/log");
1199 1199
1200 fs_var_lib(); 1200 fs_var_lib();
1201 fs_var_cache(); 1201 fs_var_cache();
1202 fs_var_utmp(); 1202 fs_var_utmp();
1203 fs_machineid(); 1203 fs_machineid();
1204 1204
1205 // don't leak user information 1205 // don't leak user information
1206 restrict_users(); 1206 restrict_users();
1207 1207
1208 // when starting as root, firejail config is not disabled; 1208 // when starting as root, firejail config is not disabled;
1209 // this mode could be used to install and test new software by chaining 1209 // this mode could be used to install and test new software by chaining
1210 // firejail sandboxes (firejail --force) 1210 // firejail sandboxes (firejail --force)
@@ -1229,10 +1229,10 @@ void fs_private_tmp(void) {
1229 if (rp) 1229 if (rp)
1230 free(rp); 1230 free(rp);
1231 } 1231 }
1232 1232
1233 // whitelist x11 directory 1233 // whitelist x11 directory
1234 profile_add("whitelist /tmp/.X11-unix"); 1234 profile_add("whitelist /tmp/.X11-unix");
1235 1235
1236 // whitelist any pulse* file in /tmp directory 1236 // whitelist any pulse* file in /tmp directory
1237 // some distros use PulseAudio sockets under /tmp instead of the socket in /urn/user 1237 // some distros use PulseAudio sockets under /tmp instead of the socket in /urn/user
1238 DIR *dir; 1238 DIR *dir;