From 4ac3130b78293b799314138e4e335c5036aeee8a Mon Sep 17 00:00:00 2001 From: netblue30 Date: Tue, 10 Jan 2017 14:29:44 -0500 Subject: chroot tightening --- src/firejail/firejail.h | 2 +- src/firejail/fs.c | 78 +++++++++++++++++++++++++++++++++++++------------ src/firejail/main.c | 7 ++--- 3 files changed, 63 insertions(+), 24 deletions(-) (limited to 'src') diff --git a/src/firejail/firejail.h b/src/firejail/firejail.h index a8208233f..586cfd65e 100644 --- a/src/firejail/firejail.h +++ b/src/firejail/firejail.h @@ -403,7 +403,7 @@ char *fs_check_overlay_dir(const char *subdirname, int allow_reuse); void fs_overlayfs(void); // chroot into an existing directory; mount exiting /dev and update /etc/resolv.conf void fs_chroot(const char *rootdir); -int fs_check_chroot_dir(const char *rootdir); +void fs_check_chroot_dir(const char *rootdir); // profile.c // find and read the profile specified by name from dir directory diff --git a/src/firejail/fs.c b/src/firejail/fs.c index 0c643af4a..d7764accd 100644 --- a/src/firejail/fs.c +++ b/src/firejail/fs.c @@ -994,20 +994,25 @@ void fs_overlayfs(void) { #ifdef HAVE_CHROOT // return 1 if error -int fs_check_chroot_dir(const char *rootdir) { +void fs_check_chroot_dir(const char *rootdir) { EUID_ASSERT(); assert(rootdir); struct stat s; char *name; + if (strcmp(rootdir, "/tmp") == 0 || strcmp(rootdir, "/var/tmp") == 0) { + fprintf(stderr, "Error: invalid chroot directory\n"); + exit(1); + } + // rootdir has to be owned by root if (stat(rootdir, &s) != 0) { fprintf(stderr, "Error: cannot find chroot directory\n"); - return 1; + exit(1); } if (s.st_uid != 0) { fprintf(stderr, "Error: chroot directory should be owned by root\n"); - return 1; + exit(1); } // check /dev @@ -1015,7 +1020,11 @@ int fs_check_chroot_dir(const char *rootdir) { errExit("asprintf"); if (stat(name, &s) == -1) { fprintf(stderr, "Error: cannot find /dev in chroot directory\n"); - return 1; + exit(1); + } + if (s.st_uid != 0) { + fprintf(stderr, "Error: chroot /dev directory should be owned by root\n"); + exit(1); } free(name); @@ -1024,7 +1033,11 @@ int fs_check_chroot_dir(const char *rootdir) { errExit("asprintf"); if (stat(name, &s) == -1) { fprintf(stderr, "Error: cannot find /var/tmp in chroot directory\n"); - return 1; + exit(1); + } + if (s.st_uid != 0) { + fprintf(stderr, "Error: chroot /var/tmp directory should be owned by root\n"); + exit(1); } free(name); @@ -1033,7 +1046,11 @@ int fs_check_chroot_dir(const char *rootdir) { errExit("asprintf"); if (stat(name, &s) == -1) { fprintf(stderr, "Error: cannot find /proc in chroot directory\n"); - return 1; + exit(1); + } + if (s.st_uid != 0) { + fprintf(stderr, "Error: chroot /proc directory should be owned by root\n"); + exit(1); } free(name); @@ -1042,18 +1059,41 @@ int fs_check_chroot_dir(const char *rootdir) { errExit("asprintf"); if (stat(name, &s) == -1) { fprintf(stderr, "Error: cannot find /tmp in chroot directory\n"); - return 1; + exit(1); + } + if (s.st_uid != 0) { + fprintf(stderr, "Error: chroot /tmp directory should be owned by root\n"); + exit(1); } free(name); - // check /bin/bash -// if (asprintf(&name, "%s/bin/bash", rootdir) == -1) -// errExit("asprintf"); -// if (stat(name, &s) == -1) { -// fprintf(stderr, "Error: cannot find /bin/bash in chroot directory\n"); -// return 1; -// } -// free(name); + // check /etc + if (asprintf(&name, "%s/etc", rootdir) == -1) + errExit("asprintf"); + if (stat(name, &s) == -1) { + fprintf(stderr, "Error: cannot find /etc in chroot directory\n"); + exit(1); + } + if (s.st_uid != 0) { + fprintf(stderr, "Error: chroot /etc directory should be owned by root\n"); + exit(1); + } + free(name); + + // check /etc/resolv.conf + if (asprintf(&name, "%s/etc/resolv.conf", rootdir) == -1) + errExit("asprintf"); + if (stat(name, &s) == 0) { + if (s.st_uid != 0) { + fprintf(stderr, "Error: chroot /etc/resolv.conf should be owned by root\n"); + exit(1); + } + } + if (is_link(name)) { + fprintf(stderr, "Error: invalid %s file\n", name); + exit(1); + } + free(name); // check x11 socket directory if (getenv("FIREJAIL_X11")) { @@ -1063,12 +1103,14 @@ int fs_check_chroot_dir(const char *rootdir) { errExit("asprintf"); if (stat(name, &s) == -1) { fprintf(stderr, "Error: cannot find /tmp/.X11-unix in chroot directory\n"); - return 1; + exit(1); + } + if (s.st_uid != 0) { + fprintf(stderr, "Error: chroot /tmp/.X11-unix directory should be owned by root\n"); + exit(1); } free(name); } - - return 0; } // chroot into an existing directory; mount exiting /dev and update /etc/resolv.conf diff --git a/src/firejail/main.c b/src/firejail/main.c index 3a347b3d9..84bf5e8e6 100644 --- a/src/firejail/main.c +++ b/src/firejail/main.c @@ -1468,13 +1468,10 @@ int main(int argc, char **argv) { fprintf(stderr, "Error: invalid chroot directory\n"); exit(1); } - free(rpath); + cfg.chrootdir = rpath; // check chroot directory structure - if (fs_check_chroot_dir(cfg.chrootdir)) { - fprintf(stderr, "Error: invalid chroot\n"); - exit(1); - } + fs_check_chroot_dir(cfg.chrootdir); } else exit_err_feature("chroot"); -- cgit v1.2.3-54-g00ecf