From e3cafb7fac7a8b17c8376616c93317c9d51cdda7 Mon Sep 17 00:00:00 2001 From: smitsohu Date: Mon, 17 Jun 2019 14:40:02 +0200 Subject: no postmount checks when building basic filesystem fixes #2782 --- src/firejail/firejail.h | 4 ++-- src/firejail/fs.c | 49 +++++++++++++++++++++++++---------------------- src/firejail/pulseaudio.c | 6 ++++-- src/firejail/sandbox.c | 2 +- src/firejail/x11.c | 6 ++++-- 5 files changed, 37 insertions(+), 30 deletions(-) (limited to 'src') 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); // mount a writable tmpfs void fs_tmpfs(const char *dir, unsigned check_owner); // remount noexec/nodev/nosuid or read-only or read-write -void fs_remount(const char *dir, OPERATION op); -void fs_remount_rec(const char *dir, OPERATION op); +void fs_remount(const char *dir, OPERATION op, unsigned check_mnt); +void fs_remount_rec(const char *dir, OPERATION op, unsigned check_mnt); // mount /proc and /sys directories void fs_proc_sys_dev_boot(void); // 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) { } } else if (op == MOUNT_READONLY | op == MOUNT_RDWR | op == MOUNT_NOEXEC) { - fs_remount_rec(fname, op); + fs_remount_rec(fname, op, 1); // todo: last_disable = SUCCESSFUL; } else if (op == MOUNT_TMPFS) { @@ -478,7 +478,7 @@ void fs_tmpfs(const char *dir, unsigned check_owner) { close(fd); } -void fs_remount(const char *dir, OPERATION op) { +void fs_remount(const char *dir, OPERATION op, unsigned check_mnt) { assert(dir); // check directory exists struct stat s; @@ -519,17 +519,19 @@ void fs_remount(const char *dir, OPERATION op) { if (mount(dir, dir, NULL, MS_BIND|MS_REC, NULL) < 0 || mount(NULL, dir, NULL, flags|MS_BIND|MS_REMOUNT, NULL) < 0) errExit("remounting"); - // run a sanity check on /proc/self/mountinfo - MountData *mptr = get_last_mount(); - size_t len = strlen(dir); - if (strncmp(mptr->dir, dir, len) != 0 || - (*(mptr->dir + len) != '\0' && *(mptr->dir + len) != '/')) - errLogExit("invalid %s mount", opstr[op]); + if (check_mnt) { + // run a sanity check on /proc/self/mountinfo + MountData *mptr = get_last_mount(); + size_t len = strlen(dir); + if (strncmp(mptr->dir, dir, len) != 0 || + (*(mptr->dir + len) != '\0' && *(mptr->dir + len) != '/')) + errLogExit("invalid %s mount", opstr[op]); + } fs_logger2(opstr[op], dir); } } -void fs_remount_rec(const char *dir, OPERATION op) { +void fs_remount_rec(const char *dir, OPERATION op, unsigned check_mnt) { assert(dir); // get mount point of the directory int mountid = get_mount_id(dir); @@ -542,7 +544,7 @@ void fs_remount_rec(const char *dir, OPERATION op) { fwarning("read-only, read-write and noexec options are not applied recursively\n"); mount_warning = 1; } - fs_remount(dir, op); + fs_remount(dir, op, check_mnt); return; } // build array with all mount points that need to get remounted @@ -551,7 +553,7 @@ void fs_remount_rec(const char *dir, OPERATION op) { // remount char **tmp = arr; while (*tmp) { - fs_remount(*tmp, op); + fs_remount(*tmp, op, check_mnt); free(*tmp++); } free(arr); @@ -720,28 +722,29 @@ static void disable_config(void) { // build a basic read-only filesystem +// top level directories could be links, run no after-mount checks void fs_basic_fs(void) { uid_t uid = getuid(); if (arg_debug) printf("Basic read-only filesystem:\n"); if (!arg_writable_etc) { - fs_remount("/etc", MOUNT_READONLY); + fs_remount("/etc", MOUNT_READONLY, 0); if (uid) - fs_remount("/etc", MOUNT_NOEXEC); + fs_remount("/etc", MOUNT_NOEXEC, 0); } if (!arg_writable_var) { - fs_remount("/var", MOUNT_READONLY); + fs_remount("/var", MOUNT_READONLY, 0); if (uid) - fs_remount("/var", MOUNT_NOEXEC); + fs_remount("/var", MOUNT_NOEXEC, 0); } - fs_remount("/bin", MOUNT_READONLY); - fs_remount("/sbin", MOUNT_READONLY); - fs_remount("/lib", MOUNT_READONLY); - fs_remount("/lib64", MOUNT_READONLY); - fs_remount("/lib32", MOUNT_READONLY); - fs_remount("/libx32", MOUNT_READONLY); - fs_remount("/usr", MOUNT_READONLY); + fs_remount("/bin", MOUNT_READONLY, 0); + fs_remount("/sbin", MOUNT_READONLY, 0); + fs_remount("/lib", MOUNT_READONLY, 0); + fs_remount("/lib64", MOUNT_READONLY, 0); + fs_remount("/lib32", MOUNT_READONLY, 0); + fs_remount("/libx32", MOUNT_READONLY, 0); + fs_remount("/usr", MOUNT_READONLY, 0); // update /var directory in order to support multiple sandboxes running on the same root directory fs_var_lock(); @@ -750,7 +753,7 @@ void fs_basic_fs(void) { if (!arg_writable_var_log) fs_var_log(); else - fs_remount("/var/log", MOUNT_RDWR); + fs_remount("/var/log", MOUNT_RDWR, 0); fs_var_lib(); 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) { if (mkdir(RUN_PULSE_DIR, 0700) == -1) errExit("mkdir"); // mount it nosuid, noexec, nodev - fs_remount(RUN_PULSE_DIR, MOUNT_NOEXEC); + fs_remount(RUN_PULSE_DIR, MOUNT_NOEXEC, 0); // create the new client.conf file char *pulsecfg = NULL; @@ -155,8 +155,10 @@ void pulseaudio_init(void) { if (fstatvfs(fd, &vfs) == -1) errExit("fstatvfs"); if ((vfs.f_flag & MS_RDONLY) == MS_RDONLY) - fs_remount(RUN_PULSE_DIR, MOUNT_READONLY); + fs_remount(RUN_PULSE_DIR, MOUNT_READONLY, 0); // mount via the link in /proc/self/fd + if (arg_debug) + printf("Mounting %s on %s\n", RUN_PULSE_DIR, homeusercfg); char *proc; if (asprintf(&proc, "/proc/self/fd/%d", fd) == -1) 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) { (void) rv; } // make seccomp filters read-only - fs_remount(RUN_SECCOMP_DIR, MOUNT_READONLY); + fs_remount(RUN_SECCOMP_DIR, MOUNT_READONLY, 0); #endif // 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) { umount("/tmp"); // remount RUN_XAUTHORITY_SEC_FILE noexec, nodev, nosuid - fs_remount(RUN_XAUTHORITY_SEC_FILE, MOUNT_NOEXEC); + fs_remount(RUN_XAUTHORITY_SEC_FILE, MOUNT_NOEXEC, 0); // Ensure there is already a file in the usual location, so that bind-mount below will work. char *dest; @@ -1202,9 +1202,11 @@ void x11_xorg(void) { if (fstatvfs(fd, &vfs) == -1) errExit("fstatvfs"); if ((vfs.f_flag & MS_RDONLY) == MS_RDONLY) - fs_remount(RUN_XAUTHORITY_SEC_FILE, MOUNT_READONLY); + fs_remount(RUN_XAUTHORITY_SEC_FILE, MOUNT_READONLY, 0); // mount via the link in /proc/self/fd + if (arg_debug) + printf("Mounting %s on %s\n", RUN_XAUTHORITY_SEC_FILE, dest); char *proc; if (asprintf(&proc, "/proc/self/fd/%d", fd) == -1) errExit("asprintf"); -- cgit v1.2.3-70-g09d2