aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/firejail/firejail.h4
-rw-r--r--src/firejail/fs.c49
-rw-r--r--src/firejail/pulseaudio.c6
-rw-r--r--src/firejail/sandbox.c2
-rw-r--r--src/firejail/x11.c6
5 files changed, 37 insertions, 30 deletions
diff --git a/src/firejail/firejail.h b/src/firejail/firejail.h
index 912a1864a..630adc3d7 100644
--- a/src/firejail/firejail.h
+++ b/src/firejail/firejail.h
@@ -379,8 +379,8 @@ void fs_blacklist(void);
379// mount a writable tmpfs 379// mount a writable tmpfs
380void fs_tmpfs(const char *dir, unsigned check_owner); 380void fs_tmpfs(const char *dir, unsigned check_owner);
381// remount noexec/nodev/nosuid or read-only or read-write 381// remount noexec/nodev/nosuid or read-only or read-write
382void fs_remount(const char *dir, OPERATION op); 382void fs_remount(const char *dir, OPERATION op, unsigned check_mnt);
383void fs_remount_rec(const char *dir, OPERATION op); 383void fs_remount_rec(const char *dir, OPERATION op, unsigned check_mnt);
384// mount /proc and /sys directories 384// mount /proc and /sys directories
385void fs_proc_sys_dev_boot(void); 385void fs_proc_sys_dev_boot(void);
386// build a basic read-only filesystem 386// build a basic read-only filesystem
diff --git a/src/firejail/fs.c b/src/firejail/fs.c
index d94f6a121..beab84dec 100644
--- a/src/firejail/fs.c
+++ b/src/firejail/fs.c
@@ -147,7 +147,7 @@ static void disable_file(OPERATION op, const char *filename) {
147 } 147 }
148 } 148 }
149 else if (op == MOUNT_READONLY | op == MOUNT_RDWR | op == MOUNT_NOEXEC) { 149 else if (op == MOUNT_READONLY | op == MOUNT_RDWR | op == MOUNT_NOEXEC) {
150 fs_remount_rec(fname, op); 150 fs_remount_rec(fname, op, 1);
151 // todo: last_disable = SUCCESSFUL; 151 // todo: last_disable = SUCCESSFUL;
152 } 152 }
153 else if (op == MOUNT_TMPFS) { 153 else if (op == MOUNT_TMPFS) {
@@ -478,7 +478,7 @@ void fs_tmpfs(const char *dir, unsigned check_owner) {
478 close(fd); 478 close(fd);
479} 479}
480 480
481void fs_remount(const char *dir, OPERATION op) { 481void fs_remount(const char *dir, OPERATION op, unsigned check_mnt) {
482 assert(dir); 482 assert(dir);
483 // check directory exists 483 // check directory exists
484 struct stat s; 484 struct stat s;
@@ -519,17 +519,19 @@ void fs_remount(const char *dir, OPERATION op) {
519 if (mount(dir, dir, NULL, MS_BIND|MS_REC, NULL) < 0 || 519 if (mount(dir, dir, NULL, MS_BIND|MS_REC, NULL) < 0 ||
520 mount(NULL, dir, NULL, flags|MS_BIND|MS_REMOUNT, NULL) < 0) 520 mount(NULL, dir, NULL, flags|MS_BIND|MS_REMOUNT, NULL) < 0)
521 errExit("remounting"); 521 errExit("remounting");
522 // run a sanity check on /proc/self/mountinfo 522 if (check_mnt) {
523 MountData *mptr = get_last_mount(); 523 // run a sanity check on /proc/self/mountinfo
524 size_t len = strlen(dir); 524 MountData *mptr = get_last_mount();
525 if (strncmp(mptr->dir, dir, len) != 0 || 525 size_t len = strlen(dir);
526 (*(mptr->dir + len) != '\0' && *(mptr->dir + len) != '/')) 526 if (strncmp(mptr->dir, dir, len) != 0 ||
527 errLogExit("invalid %s mount", opstr[op]); 527 (*(mptr->dir + len) != '\0' && *(mptr->dir + len) != '/'))
528 errLogExit("invalid %s mount", opstr[op]);
529 }
528 fs_logger2(opstr[op], dir); 530 fs_logger2(opstr[op], dir);
529 } 531 }
530} 532}
531 533
532void fs_remount_rec(const char *dir, OPERATION op) { 534void fs_remount_rec(const char *dir, OPERATION op, unsigned check_mnt) {
533 assert(dir); 535 assert(dir);
534 // get mount point of the directory 536 // get mount point of the directory
535 int mountid = get_mount_id(dir); 537 int mountid = get_mount_id(dir);
@@ -542,7 +544,7 @@ void fs_remount_rec(const char *dir, OPERATION op) {
542 fwarning("read-only, read-write and noexec options are not applied recursively\n"); 544 fwarning("read-only, read-write and noexec options are not applied recursively\n");
543 mount_warning = 1; 545 mount_warning = 1;
544 } 546 }
545 fs_remount(dir, op); 547 fs_remount(dir, op, check_mnt);
546 return; 548 return;
547 } 549 }
548 // build array with all mount points that need to get remounted 550 // build array with all mount points that need to get remounted
@@ -551,7 +553,7 @@ void fs_remount_rec(const char *dir, OPERATION op) {
551 // remount 553 // remount
552 char **tmp = arr; 554 char **tmp = arr;
553 while (*tmp) { 555 while (*tmp) {
554 fs_remount(*tmp, op); 556 fs_remount(*tmp, op, check_mnt);
555 free(*tmp++); 557 free(*tmp++);
556 } 558 }
557 free(arr); 559 free(arr);
@@ -720,28 +722,29 @@ static void disable_config(void) {
720 722
721 723
722// build a basic read-only filesystem 724// build a basic read-only filesystem
725// top level directories could be links, run no after-mount checks
723void fs_basic_fs(void) { 726void fs_basic_fs(void) {
724 uid_t uid = getuid(); 727 uid_t uid = getuid();
725 728
726 if (arg_debug) 729 if (arg_debug)
727 printf("Basic read-only filesystem:\n"); 730 printf("Basic read-only filesystem:\n");
728 if (!arg_writable_etc) { 731 if (!arg_writable_etc) {
729 fs_remount("/etc", MOUNT_READONLY); 732 fs_remount("/etc", MOUNT_READONLY, 0);
730 if (uid) 733 if (uid)
731 fs_remount("/etc", MOUNT_NOEXEC); 734 fs_remount("/etc", MOUNT_NOEXEC, 0);
732 } 735 }
733 if (!arg_writable_var) { 736 if (!arg_writable_var) {
734 fs_remount("/var", MOUNT_READONLY); 737 fs_remount("/var", MOUNT_READONLY, 0);
735 if (uid) 738 if (uid)
736 fs_remount("/var", MOUNT_NOEXEC); 739 fs_remount("/var", MOUNT_NOEXEC, 0);
737 } 740 }
738 fs_remount("/bin", MOUNT_READONLY); 741 fs_remount("/bin", MOUNT_READONLY, 0);
739 fs_remount("/sbin", MOUNT_READONLY); 742 fs_remount("/sbin", MOUNT_READONLY, 0);
740 fs_remount("/lib", MOUNT_READONLY); 743 fs_remount("/lib", MOUNT_READONLY, 0);
741 fs_remount("/lib64", MOUNT_READONLY); 744 fs_remount("/lib64", MOUNT_READONLY, 0);
742 fs_remount("/lib32", MOUNT_READONLY); 745 fs_remount("/lib32", MOUNT_READONLY, 0);
743 fs_remount("/libx32", MOUNT_READONLY); 746 fs_remount("/libx32", MOUNT_READONLY, 0);
744 fs_remount("/usr", MOUNT_READONLY); 747 fs_remount("/usr", MOUNT_READONLY, 0);
745 748
746 // update /var directory in order to support multiple sandboxes running on the same root directory 749 // update /var directory in order to support multiple sandboxes running on the same root directory
747 fs_var_lock(); 750 fs_var_lock();
@@ -750,7 +753,7 @@ void fs_basic_fs(void) {
750 if (!arg_writable_var_log) 753 if (!arg_writable_var_log)
751 fs_var_log(); 754 fs_var_log();
752 else 755 else
753 fs_remount("/var/log", MOUNT_RDWR); 756 fs_remount("/var/log", MOUNT_RDWR, 0);
754 757
755 fs_var_lib(); 758 fs_var_lib();
756 fs_var_cache(); 759 fs_var_cache();
diff --git a/src/firejail/pulseaudio.c b/src/firejail/pulseaudio.c
index a62d123ae..b82473476 100644
--- a/src/firejail/pulseaudio.c
+++ b/src/firejail/pulseaudio.c
@@ -88,7 +88,7 @@ void pulseaudio_init(void) {
88 if (mkdir(RUN_PULSE_DIR, 0700) == -1) 88 if (mkdir(RUN_PULSE_DIR, 0700) == -1)
89 errExit("mkdir"); 89 errExit("mkdir");
90 // mount it nosuid, noexec, nodev 90 // mount it nosuid, noexec, nodev
91 fs_remount(RUN_PULSE_DIR, MOUNT_NOEXEC); 91 fs_remount(RUN_PULSE_DIR, MOUNT_NOEXEC, 0);
92 92
93 // create the new client.conf file 93 // create the new client.conf file
94 char *pulsecfg = NULL; 94 char *pulsecfg = NULL;
@@ -155,8 +155,10 @@ void pulseaudio_init(void) {
155 if (fstatvfs(fd, &vfs) == -1) 155 if (fstatvfs(fd, &vfs) == -1)
156 errExit("fstatvfs"); 156 errExit("fstatvfs");
157 if ((vfs.f_flag & MS_RDONLY) == MS_RDONLY) 157 if ((vfs.f_flag & MS_RDONLY) == MS_RDONLY)
158 fs_remount(RUN_PULSE_DIR, MOUNT_READONLY); 158 fs_remount(RUN_PULSE_DIR, MOUNT_READONLY, 0);
159 // mount via the link in /proc/self/fd 159 // mount via the link in /proc/self/fd
160 if (arg_debug)
161 printf("Mounting %s on %s\n", RUN_PULSE_DIR, homeusercfg);
160 char *proc; 162 char *proc;
161 if (asprintf(&proc, "/proc/self/fd/%d", fd) == -1) 163 if (asprintf(&proc, "/proc/self/fd/%d", fd) == -1)
162 errExit("asprintf"); 164 errExit("asprintf");
diff --git a/src/firejail/sandbox.c b/src/firejail/sandbox.c
index 0c08a76c6..43fd6af77 100644
--- a/src/firejail/sandbox.c
+++ b/src/firejail/sandbox.c
@@ -1106,7 +1106,7 @@ int sandbox(void* sandbox_arg) {
1106 (void) rv; 1106 (void) rv;
1107 } 1107 }
1108 // make seccomp filters read-only 1108 // make seccomp filters read-only
1109 fs_remount(RUN_SECCOMP_DIR, MOUNT_READONLY); 1109 fs_remount(RUN_SECCOMP_DIR, MOUNT_READONLY, 0);
1110#endif 1110#endif
1111 1111
1112 // set capabilities 1112 // set capabilities
diff --git a/src/firejail/x11.c b/src/firejail/x11.c
index 7cfc5b683..69a9a7bee 100644
--- a/src/firejail/x11.c
+++ b/src/firejail/x11.c
@@ -1169,7 +1169,7 @@ void x11_xorg(void) {
1169 umount("/tmp"); 1169 umount("/tmp");
1170 1170
1171 // remount RUN_XAUTHORITY_SEC_FILE noexec, nodev, nosuid 1171 // remount RUN_XAUTHORITY_SEC_FILE noexec, nodev, nosuid
1172 fs_remount(RUN_XAUTHORITY_SEC_FILE, MOUNT_NOEXEC); 1172 fs_remount(RUN_XAUTHORITY_SEC_FILE, MOUNT_NOEXEC, 0);
1173 1173
1174 // Ensure there is already a file in the usual location, so that bind-mount below will work. 1174 // Ensure there is already a file in the usual location, so that bind-mount below will work.
1175 char *dest; 1175 char *dest;
@@ -1202,9 +1202,11 @@ void x11_xorg(void) {
1202 if (fstatvfs(fd, &vfs) == -1) 1202 if (fstatvfs(fd, &vfs) == -1)
1203 errExit("fstatvfs"); 1203 errExit("fstatvfs");
1204 if ((vfs.f_flag & MS_RDONLY) == MS_RDONLY) 1204 if ((vfs.f_flag & MS_RDONLY) == MS_RDONLY)
1205 fs_remount(RUN_XAUTHORITY_SEC_FILE, MOUNT_READONLY); 1205 fs_remount(RUN_XAUTHORITY_SEC_FILE, MOUNT_READONLY, 0);
1206 1206
1207 // mount via the link in /proc/self/fd 1207 // mount via the link in /proc/self/fd
1208 if (arg_debug)
1209 printf("Mounting %s on %s\n", RUN_XAUTHORITY_SEC_FILE, dest);
1208 char *proc; 1210 char *proc;
1209 if (asprintf(&proc, "/proc/self/fd/%d", fd) == -1) 1211 if (asprintf(&proc, "/proc/self/fd/%d", fd) == -1)
1210 errExit("asprintf"); 1212 errExit("asprintf");