diff options
author | netblue30 <netblue30@yahoo.com> | 2017-01-10 14:29:44 -0500 |
---|---|---|
committer | netblue30 <netblue30@yahoo.com> | 2017-01-10 14:29:44 -0500 |
commit | 4ac3130b78293b799314138e4e335c5036aeee8a (patch) | |
tree | 58fdf5484284b1f802b8972244f7babca4c0052f /src | |
parent | copy_file cleanup (diff) | |
download | firejail-4ac3130b78293b799314138e4e335c5036aeee8a.tar.gz firejail-4ac3130b78293b799314138e4e335c5036aeee8a.tar.zst firejail-4ac3130b78293b799314138e4e335c5036aeee8a.zip |
chroot tightening
Diffstat (limited to 'src')
-rw-r--r-- | src/firejail/firejail.h | 2 | ||||
-rw-r--r-- | src/firejail/fs.c | 78 | ||||
-rw-r--r-- | src/firejail/main.c | 7 |
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); | |||
403 | void fs_overlayfs(void); | 403 | void 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 |
405 | void fs_chroot(const char *rootdir); | 405 | void fs_chroot(const char *rootdir); |
406 | int fs_check_chroot_dir(const char *rootdir); | 406 | void 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 |
997 | int fs_check_chroot_dir(const char *rootdir) { | 997 | void 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"); |