aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorLibravatar netblue30 <netblue30@yahoo.com>2017-01-10 14:29:44 -0500
committerLibravatar netblue30 <netblue30@yahoo.com>2017-01-10 14:29:44 -0500
commit4ac3130b78293b799314138e4e335c5036aeee8a (patch)
tree58fdf5484284b1f802b8972244f7babca4c0052f /src
parentcopy_file cleanup (diff)
downloadfirejail-4ac3130b78293b799314138e4e335c5036aeee8a.tar.gz
firejail-4ac3130b78293b799314138e4e335c5036aeee8a.tar.zst
firejail-4ac3130b78293b799314138e4e335c5036aeee8a.zip
chroot tightening
Diffstat (limited to 'src')
-rw-r--r--src/firejail/firejail.h2
-rw-r--r--src/firejail/fs.c78
-rw-r--r--src/firejail/main.c7
3 files changed, 63 insertions, 24 deletions
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);
403void fs_overlayfs(void); 403void fs_overlayfs(void);
404// chroot into an existing directory; mount exiting /dev and update /etc/resolv.conf 404// chroot into an existing directory; mount exiting /dev and update /etc/resolv.conf
405void fs_chroot(const char *rootdir); 405void fs_chroot(const char *rootdir);
406int fs_check_chroot_dir(const char *rootdir); 406void fs_check_chroot_dir(const char *rootdir);
407 407
408// profile.c 408// profile.c
409// find and read the profile specified by name from dir directory 409// 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) {
994 994
995#ifdef HAVE_CHROOT 995#ifdef HAVE_CHROOT
996// return 1 if error 996// return 1 if error
997int fs_check_chroot_dir(const char *rootdir) { 997void fs_check_chroot_dir(const char *rootdir) {
998 EUID_ASSERT(); 998 EUID_ASSERT();
999 assert(rootdir); 999 assert(rootdir);
1000 struct stat s; 1000 struct stat s;
1001 char *name; 1001 char *name;
1002 1002
1003 if (strcmp(rootdir, "/tmp") == 0 || strcmp(rootdir, "/var/tmp") == 0) {
1004 fprintf(stderr, "Error: invalid chroot directory\n");
1005 exit(1);
1006 }
1007
1003 // rootdir has to be owned by root 1008 // rootdir has to be owned by root
1004 if (stat(rootdir, &s) != 0) { 1009 if (stat(rootdir, &s) != 0) {
1005 fprintf(stderr, "Error: cannot find chroot directory\n"); 1010 fprintf(stderr, "Error: cannot find chroot directory\n");
1006 return 1; 1011 exit(1);
1007 } 1012 }
1008 if (s.st_uid != 0) { 1013 if (s.st_uid != 0) {
1009 fprintf(stderr, "Error: chroot directory should be owned by root\n"); 1014 fprintf(stderr, "Error: chroot directory should be owned by root\n");
1010 return 1; 1015 exit(1);
1011 } 1016 }
1012 1017
1013 // check /dev 1018 // check /dev
@@ -1015,7 +1020,11 @@ int fs_check_chroot_dir(const char *rootdir) {
1015 errExit("asprintf"); 1020 errExit("asprintf");
1016 if (stat(name, &s) == -1) { 1021 if (stat(name, &s) == -1) {
1017 fprintf(stderr, "Error: cannot find /dev in chroot directory\n"); 1022 fprintf(stderr, "Error: cannot find /dev in chroot directory\n");
1018 return 1; 1023 exit(1);
1024 }
1025 if (s.st_uid != 0) {
1026 fprintf(stderr, "Error: chroot /dev directory should be owned by root\n");
1027 exit(1);
1019 } 1028 }
1020 free(name); 1029 free(name);
1021 1030
@@ -1024,7 +1033,11 @@ int fs_check_chroot_dir(const char *rootdir) {
1024 errExit("asprintf"); 1033 errExit("asprintf");
1025 if (stat(name, &s) == -1) { 1034 if (stat(name, &s) == -1) {
1026 fprintf(stderr, "Error: cannot find /var/tmp in chroot directory\n"); 1035 fprintf(stderr, "Error: cannot find /var/tmp in chroot directory\n");
1027 return 1; 1036 exit(1);
1037 }
1038 if (s.st_uid != 0) {
1039 fprintf(stderr, "Error: chroot /var/tmp directory should be owned by root\n");
1040 exit(1);
1028 } 1041 }
1029 free(name); 1042 free(name);
1030 1043
@@ -1033,7 +1046,11 @@ int fs_check_chroot_dir(const char *rootdir) {
1033 errExit("asprintf"); 1046 errExit("asprintf");
1034 if (stat(name, &s) == -1) { 1047 if (stat(name, &s) == -1) {
1035 fprintf(stderr, "Error: cannot find /proc in chroot directory\n"); 1048 fprintf(stderr, "Error: cannot find /proc in chroot directory\n");
1036 return 1; 1049 exit(1);
1050 }
1051 if (s.st_uid != 0) {
1052 fprintf(stderr, "Error: chroot /proc directory should be owned by root\n");
1053 exit(1);
1037 } 1054 }
1038 free(name); 1055 free(name);
1039 1056
@@ -1042,18 +1059,41 @@ int fs_check_chroot_dir(const char *rootdir) {
1042 errExit("asprintf"); 1059 errExit("asprintf");
1043 if (stat(name, &s) == -1) { 1060 if (stat(name, &s) == -1) {
1044 fprintf(stderr, "Error: cannot find /tmp in chroot directory\n"); 1061 fprintf(stderr, "Error: cannot find /tmp in chroot directory\n");
1045 return 1; 1062 exit(1);
1063 }
1064 if (s.st_uid != 0) {
1065 fprintf(stderr, "Error: chroot /tmp directory should be owned by root\n");
1066 exit(1);
1046 } 1067 }
1047 free(name); 1068 free(name);
1048 1069
1049 // check /bin/bash 1070 // check /etc
1050// if (asprintf(&name, "%s/bin/bash", rootdir) == -1) 1071 if (asprintf(&name, "%s/etc", rootdir) == -1)
1051// errExit("asprintf"); 1072 errExit("asprintf");
1052// if (stat(name, &s) == -1) { 1073 if (stat(name, &s) == -1) {
1053// fprintf(stderr, "Error: cannot find /bin/bash in chroot directory\n"); 1074 fprintf(stderr, "Error: cannot find /etc in chroot directory\n");
1054// return 1; 1075 exit(1);
1055// } 1076 }
1056// free(name); 1077 if (s.st_uid != 0) {
1078 fprintf(stderr, "Error: chroot /etc directory should be owned by root\n");
1079 exit(1);
1080 }
1081 free(name);
1082
1083 // check /etc/resolv.conf
1084 if (asprintf(&name, "%s/etc/resolv.conf", rootdir) == -1)
1085 errExit("asprintf");
1086 if (stat(name, &s) == 0) {
1087 if (s.st_uid != 0) {
1088 fprintf(stderr, "Error: chroot /etc/resolv.conf should be owned by root\n");
1089 exit(1);
1090 }
1091 }
1092 if (is_link(name)) {
1093 fprintf(stderr, "Error: invalid %s file\n", name);
1094 exit(1);
1095 }
1096 free(name);
1057 1097
1058 // check x11 socket directory 1098 // check x11 socket directory
1059 if (getenv("FIREJAIL_X11")) { 1099 if (getenv("FIREJAIL_X11")) {
@@ -1063,12 +1103,14 @@ int fs_check_chroot_dir(const char *rootdir) {
1063 errExit("asprintf"); 1103 errExit("asprintf");
1064 if (stat(name, &s) == -1) { 1104 if (stat(name, &s) == -1) {
1065 fprintf(stderr, "Error: cannot find /tmp/.X11-unix in chroot directory\n"); 1105 fprintf(stderr, "Error: cannot find /tmp/.X11-unix in chroot directory\n");
1066 return 1; 1106 exit(1);
1107 }
1108 if (s.st_uid != 0) {
1109 fprintf(stderr, "Error: chroot /tmp/.X11-unix directory should be owned by root\n");
1110 exit(1);
1067 } 1111 }
1068 free(name); 1112 free(name);
1069 } 1113 }
1070
1071 return 0;
1072} 1114}
1073 1115
1074// chroot into an existing directory; mount exiting /dev and update /etc/resolv.conf 1116// 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) {
1468 fprintf(stderr, "Error: invalid chroot directory\n"); 1468 fprintf(stderr, "Error: invalid chroot directory\n");
1469 exit(1); 1469 exit(1);
1470 } 1470 }
1471 free(rpath); 1471 cfg.chrootdir = rpath;
1472 1472
1473 // check chroot directory structure 1473 // check chroot directory structure
1474 if (fs_check_chroot_dir(cfg.chrootdir)) { 1474 fs_check_chroot_dir(cfg.chrootdir);
1475 fprintf(stderr, "Error: invalid chroot\n");
1476 exit(1);
1477 }
1478 } 1475 }
1479 else 1476 else
1480 exit_err_feature("chroot"); 1477 exit_err_feature("chroot");