diff options
author | Adis Hamzić <adis@hamzadis.com> | 2016-08-12 18:06:47 +0200 |
---|---|---|
committer | Adis Hamzić <adis@hamzadis.com> | 2016-08-12 18:06:47 +0200 |
commit | 32e6cb2b6425b48c9cc2d456f81460ec6b3fc5b3 (patch) | |
tree | 9b62c2e0d85903d5c26ca3257cb0384d8547c777 /src | |
parent | x11 support rewrite (diff) | |
download | firejail-32e6cb2b6425b48c9cc2d456f81460ec6b3fc5b3.tar.gz firejail-32e6cb2b6425b48c9cc2d456f81460ec6b3fc5b3.tar.zst firejail-32e6cb2b6425b48c9cc2d456f81460ec6b3fc5b3.zip |
added more overlay options
Diffstat (limited to 'src')
-rw-r--r-- | src/firejail/firejail.h | 3 | ||||
-rw-r--r-- | src/firejail/fs.c | 54 | ||||
-rw-r--r-- | src/firejail/main.c | 100 | ||||
-rw-r--r-- | src/firejail/usage.c | 18 | ||||
-rw-r--r-- | src/man/firejail.txt | 44 |
5 files changed, 176 insertions, 43 deletions
diff --git a/src/firejail/firejail.h b/src/firejail/firejail.h index 16b9d468f..ee70f19f1 100644 --- a/src/firejail/firejail.h +++ b/src/firejail/firejail.h | |||
@@ -221,7 +221,8 @@ extern int arg_debug_whitelists; // print debug messages for whitelists | |||
221 | extern int arg_nonetwork; // --net=none | 221 | extern int arg_nonetwork; // --net=none |
222 | extern int arg_command; // -c | 222 | extern int arg_command; // -c |
223 | extern int arg_overlay; // overlay option | 223 | extern int arg_overlay; // overlay option |
224 | extern int arg_overlay_keep; // place overlay diff directory in ~/.firejail | 224 | extern int arg_overlay_keep; // place overlay diff in a known directory |
225 | extern int arg_overlay_reuse; // allow the reuse of overlays | ||
225 | extern int arg_zsh; // use zsh as default shell | 226 | extern int arg_zsh; // use zsh as default shell |
226 | extern int arg_csh; // use csh as default shell | 227 | extern int arg_csh; // use csh as default shell |
227 | 228 | ||
diff --git a/src/firejail/fs.c b/src/firejail/fs.c index 86126672e..c152abe0d 100644 --- a/src/firejail/fs.c +++ b/src/firejail/fs.c | |||
@@ -879,21 +879,37 @@ void fs_overlayfs(void) { | |||
879 | if (chmod(oroot, 0755) < 0) | 879 | if (chmod(oroot, 0755) < 0) |
880 | errExit("chmod"); | 880 | errExit("chmod"); |
881 | 881 | ||
882 | struct stat s; | ||
882 | char *basedir = RUN_MNT_DIR; | 883 | char *basedir = RUN_MNT_DIR; |
883 | if (arg_overlay_keep) { | 884 | if (arg_overlay_keep) { |
884 | // set base for working and diff directories | 885 | // set base for working and diff directories |
885 | basedir = cfg.overlay_dir; | 886 | basedir = cfg.overlay_dir; |
886 | if (mkdir(basedir, 0755) != 0) { | 887 | |
887 | fprintf(stderr, "Error: cannot create overlay directory\n"); | 888 | // does the overlay exist? |
888 | exit(1); | 889 | if (stat(basedir, &s) == 0) { |
890 | if (arg_overlay_reuse == 0) { | ||
891 | fprintf(stderr, "Error: overlay directory exists, but reuse is not allowed\n"); | ||
892 | exit(1); | ||
893 | } | ||
894 | } | ||
895 | else { | ||
896 | if (mkdir(basedir, 0755) != 0) { | ||
897 | fprintf(stderr, "Error: cannot create overlay directory\n"); | ||
898 | exit(1); | ||
899 | } | ||
889 | } | 900 | } |
890 | } | 901 | } |
891 | 902 | ||
892 | char *odiff; | 903 | char *odiff; |
893 | if(asprintf(&odiff, "%s/odiff", basedir) == -1) | 904 | if(asprintf(&odiff, "%s/odiff", basedir) == -1) |
894 | errExit("asprintf"); | 905 | errExit("asprintf"); |
895 | if (mkdir(odiff, 0755)) | 906 | |
896 | errExit("mkdir"); | 907 | // no need to check arg_overlay_reuse |
908 | if (stat(odiff, &s) != 0) { | ||
909 | if (mkdir(odiff, 0755)) | ||
910 | errExit("mkdir"); | ||
911 | } | ||
912 | |||
897 | if (chown(odiff, 0, 0) < 0) | 913 | if (chown(odiff, 0, 0) < 0) |
898 | errExit("chown"); | 914 | errExit("chown"); |
899 | if (chmod(odiff, 0755) < 0) | 915 | if (chmod(odiff, 0755) < 0) |
@@ -902,8 +918,13 @@ void fs_overlayfs(void) { | |||
902 | char *owork; | 918 | char *owork; |
903 | if(asprintf(&owork, "%s/owork", basedir) == -1) | 919 | if(asprintf(&owork, "%s/owork", basedir) == -1) |
904 | errExit("asprintf"); | 920 | errExit("asprintf"); |
905 | if (mkdir(owork, 0755)) | 921 | |
906 | errExit("mkdir"); | 922 | // no need to check arg_overlay_reuse |
923 | if (stat(owork, &s) != 0) { | ||
924 | if (mkdir(owork, 0755)) | ||
925 | errExit("mkdir"); | ||
926 | } | ||
927 | |||
907 | if (chown(owork, 0, 0) < 0) | 928 | if (chown(owork, 0, 0) < 0) |
908 | errExit("chown"); | 929 | errExit("chown"); |
909 | if (chmod(owork, 0755) < 0) | 930 | if (chmod(owork, 0755) < 0) |
@@ -959,8 +980,13 @@ void fs_overlayfs(void) { | |||
959 | 980 | ||
960 | if(asprintf(&hdiff, "%s/hdiff", basedir) == -1) | 981 | if(asprintf(&hdiff, "%s/hdiff", basedir) == -1) |
961 | errExit("asprintf"); | 982 | errExit("asprintf"); |
962 | if (mkdir(hdiff, S_IRWXU | S_IRWXG | S_IRWXO)) | 983 | |
963 | errExit("mkdir"); | 984 | // no need to check arg_overlay_reuse |
985 | if (stat(hdiff, &s) != 0) { | ||
986 | if (mkdir(hdiff, S_IRWXU | S_IRWXG | S_IRWXO)) | ||
987 | errExit("mkdir"); | ||
988 | } | ||
989 | |||
964 | if (chown(hdiff, 0, 0) < 0) | 990 | if (chown(hdiff, 0, 0) < 0) |
965 | errExit("chown"); | 991 | errExit("chown"); |
966 | if (chmod(hdiff, S_IRWXU | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH) < 0) | 992 | if (chmod(hdiff, S_IRWXU | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH) < 0) |
@@ -968,8 +994,13 @@ void fs_overlayfs(void) { | |||
968 | 994 | ||
969 | if(asprintf(&hwork, "%s/hwork", basedir) == -1) | 995 | if(asprintf(&hwork, "%s/hwork", basedir) == -1) |
970 | errExit("asprintf"); | 996 | errExit("asprintf"); |
971 | if (mkdir(hwork, S_IRWXU | S_IRWXG | S_IRWXO)) | 997 | |
972 | errExit("mkdir"); | 998 | // no need to check arg_overlay_reuse |
999 | if (stat(hwork, &s) != 0) { | ||
1000 | if (mkdir(hwork, S_IRWXU | S_IRWXG | S_IRWXO)) | ||
1001 | errExit("mkdir"); | ||
1002 | } | ||
1003 | |||
973 | if (chown(hwork, 0, 0) < 0) | 1004 | if (chown(hwork, 0, 0) < 0) |
974 | errExit("chown"); | 1005 | errExit("chown"); |
975 | if (chmod(hwork, S_IRWXU | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH) < 0) | 1006 | if (chmod(hwork, S_IRWXU | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH) < 0) |
@@ -1011,7 +1042,6 @@ void fs_overlayfs(void) { | |||
1011 | fs_logger("whitelist /run"); | 1042 | fs_logger("whitelist /run"); |
1012 | 1043 | ||
1013 | // mount-bind /tmp/.X11-unix directory | 1044 | // mount-bind /tmp/.X11-unix directory |
1014 | struct stat s; | ||
1015 | if (stat("/tmp/.X11-unix", &s) == 0) { | 1045 | if (stat("/tmp/.X11-unix", &s) == 0) { |
1016 | if (arg_debug) | 1046 | if (arg_debug) |
1017 | printf("Mounting /tmp/.X11-unix\n"); | 1047 | printf("Mounting /tmp/.X11-unix\n"); |
diff --git a/src/firejail/main.c b/src/firejail/main.c index acae7c3dd..120809456 100644 --- a/src/firejail/main.c +++ b/src/firejail/main.c | |||
@@ -59,7 +59,8 @@ int arg_debug_whitelists; // print debug messages for whitelists | |||
59 | int arg_nonetwork = 0; // --net=none | 59 | int arg_nonetwork = 0; // --net=none |
60 | int arg_command = 0; // -c | 60 | int arg_command = 0; // -c |
61 | int arg_overlay = 0; // overlay option | 61 | int arg_overlay = 0; // overlay option |
62 | int arg_overlay_keep = 0; // place overlay diff directory in ~/.firejail | 62 | int arg_overlay_keep = 0; // place overlay diff in a known directory |
63 | int arg_overlay_reuse = 0; // allow the reuse of overlays | ||
63 | int arg_zsh = 0; // use zsh as default shell | 64 | int arg_zsh = 0; // use zsh as default shell |
64 | int arg_csh = 0; // use csh as default shell | 65 | int arg_csh = 0; // use csh as default shell |
65 | 66 | ||
@@ -691,6 +692,41 @@ static void delete_x11_file(pid_t pid) { | |||
691 | free(fname); | 692 | free(fname); |
692 | } | 693 | } |
693 | 694 | ||
695 | static char *create_and_check_overlay_dir(const char *subdirname, int allow_reuse) { | ||
696 | // create ~/.firejail directory | ||
697 | struct stat s; | ||
698 | char *dirname; | ||
699 | if (asprintf(&dirname, "%s/.firejail", cfg.homedir) == -1) | ||
700 | errExit("asprintf"); | ||
701 | if (stat(dirname, &s) == -1) { | ||
702 | /* coverity[toctou] */ | ||
703 | if (mkdir(dirname, 0700)) | ||
704 | errExit("mkdir"); | ||
705 | if (chown(dirname, getuid(), getgid()) < 0) | ||
706 | errExit("chown"); | ||
707 | if (chmod(dirname, 0700) < 0) | ||
708 | errExit("chmod"); | ||
709 | } | ||
710 | else if (is_link(dirname)) { | ||
711 | fprintf(stderr, "Error: invalid ~/.firejail directory\n"); | ||
712 | exit(1); | ||
713 | } | ||
714 | |||
715 | free(dirname); | ||
716 | |||
717 | // check overlay directory | ||
718 | if (asprintf(&dirname, "%s/.firejail/%s", cfg.homedir, subdirname) == -1) | ||
719 | errExit("asprintf"); | ||
720 | if (allow_reuse == 0) { | ||
721 | if (stat(dirname, &s) == 0) { | ||
722 | fprintf(stderr, "Error: overlay directory already exists: %s\n", dirname); | ||
723 | exit(1); | ||
724 | } | ||
725 | } | ||
726 | |||
727 | return dirname; | ||
728 | } | ||
729 | |||
694 | static void detect_quiet(int argc, char **argv) { | 730 | static void detect_quiet(int argc, char **argv) { |
695 | int i; | 731 | int i; |
696 | 732 | ||
@@ -1193,34 +1229,54 @@ int main(int argc, char **argv) { | |||
1193 | arg_overlay = 1; | 1229 | arg_overlay = 1; |
1194 | arg_overlay_keep = 1; | 1230 | arg_overlay_keep = 1; |
1195 | 1231 | ||
1196 | // create ~/.firejail directory | 1232 | char *subdirname; |
1197 | char *dirname; | 1233 | if (asprintf(&subdirname, "%d", getpid()) == -1) |
1198 | if (asprintf(&dirname, "%s/.firejail", cfg.homedir) == -1) | ||
1199 | errExit("asprintf"); | 1234 | errExit("asprintf"); |
1200 | if (stat(dirname, &s) == -1) { | 1235 | cfg.overlay_dir = create_and_check_overlay_dir(subdirname, arg_overlay_reuse); |
1201 | /* coverity[toctou] */ | 1236 | |
1202 | if (mkdir(dirname, 0700)) | 1237 | free(subdirname); |
1203 | errExit("mkdir"); | 1238 | } |
1204 | if (chown(dirname, getuid(), getgid()) < 0) | 1239 | else if (strncmp(argv[i], "--overlay-named=", 16) == 0) { |
1205 | errExit("chown"); | 1240 | if (cfg.chrootdir) { |
1206 | if (chmod(dirname, 0700) < 0) | 1241 | fprintf(stderr, "Error: --overlay and --chroot options are mutually exclusive\n"); |
1207 | errExit("chmod"); | 1242 | exit(1); |
1208 | } | 1243 | } |
1209 | else if (is_link(dirname)) { | 1244 | struct stat s; |
1210 | fprintf(stderr, "Error: invalid ~/.firejail directory\n"); | 1245 | if (stat("/proc/sys/kernel/grsecurity", &s) == 0) { |
1246 | fprintf(stderr, "Error: --overlay option is not available on Grsecurity systems\n"); | ||
1211 | exit(1); | 1247 | exit(1); |
1212 | } | 1248 | } |
1249 | arg_overlay = 1; | ||
1250 | arg_overlay_keep = 1; | ||
1251 | arg_overlay_reuse = 1; | ||
1213 | 1252 | ||
1214 | free(dirname); | 1253 | char *subdirname = argv[i] + 16; |
1254 | if (subdirname == '\0') { | ||
1255 | fprintf(stderr, "Error: invalid overlay option\n"); | ||
1256 | exit(1); | ||
1257 | } | ||
1258 | cfg.overlay_dir = create_and_check_overlay_dir(subdirname, arg_overlay_reuse); | ||
1259 | } | ||
1260 | else if (strncmp(argv[i], "--overlay-path=", 15) == 0) { | ||
1261 | if (cfg.chrootdir) { | ||
1262 | fprintf(stderr, "Error: --overlay and --chroot options are mutually exclusive\n"); | ||
1263 | exit(1); | ||
1264 | } | ||
1265 | struct stat s; | ||
1266 | if (stat("/proc/sys/kernel/grsecurity", &s) == 0) { | ||
1267 | fprintf(stderr, "Error: --overlay option is not available on Grsecurity systems\n"); | ||
1268 | exit(1); | ||
1269 | } | ||
1270 | arg_overlay = 1; | ||
1271 | arg_overlay_keep = 1; | ||
1272 | arg_overlay_reuse = 1; | ||
1215 | 1273 | ||
1216 | // check overlay directory | 1274 | char *dirname = argv[i] + 15; |
1217 | if (asprintf(&dirname, "%s/.firejail/%d", cfg.homedir, getpid()) == -1) | 1275 | if (dirname == '\0') { |
1218 | errExit("asprintf"); | 1276 | fprintf(stderr, "Error: invalid overlay option\n"); |
1219 | if (stat(dirname, &s) == 0) { | ||
1220 | fprintf(stderr, "Error: overlay directory already exists: %s\n", dirname); | ||
1221 | exit(1); | 1277 | exit(1); |
1222 | } | 1278 | } |
1223 | cfg.overlay_dir = dirname; | 1279 | cfg.overlay_dir = expand_home(dirname, cfg.homedir); |
1224 | } | 1280 | } |
1225 | else if (strcmp(argv[i], "--overlay-tmpfs") == 0) { | 1281 | else if (strcmp(argv[i], "--overlay-tmpfs") == 0) { |
1226 | if (cfg.chrootdir) { | 1282 | if (cfg.chrootdir) { |
diff --git a/src/firejail/usage.c b/src/firejail/usage.c index 03558cca7..ed6d22e69 100644 --- a/src/firejail/usage.c +++ b/src/firejail/usage.c | |||
@@ -176,16 +176,26 @@ void usage(void) { | |||
176 | 176 | ||
177 | printf(" --overlay - mount a filesystem overlay on top of the current filesystem.\n"); | 177 | printf(" --overlay - mount a filesystem overlay on top of the current filesystem.\n"); |
178 | printf("\tThe upper filesystem layer is persistent, and stored in\n"); | 178 | printf("\tThe upper filesystem layer is persistent, and stored in\n"); |
179 | printf("\t$HOME/.firejail directory. (OverlayFS support is required in\n"); | 179 | printf("\t$HOME/.firejail/<PID> directory. (OverlayFS support is required in\n"); |
180 | printf("\tLinux kernel for this option to work). \n\n"); | 180 | printf("\tLinux kernel for this option to work). \n\n"); |
181 | |||
182 | printf(" --overlay-named=name - mount a filesystem overlay on top of the current\n"); | ||
183 | printf("\tfilesystem. The upper filesystem layer is persistent, and stored in\n"); | ||
184 | printf("\t$HOME/.firejail/<NAME> directory. (OverlayFS support is required in\n"); | ||
185 | printf("\tLinux kernel for this option to work). \n\n"); | ||
186 | |||
187 | printf(" --overlay-path=path - mount a filesystem overlay on top of the current\n"); | ||
188 | printf("\tfilesystem. The upper filesystem layer is persistent, and stored in\n"); | ||
189 | printf("\tthe specified path. (OverlayFS support is required in Linux kernel for\n"); | ||
190 | printf("\tthis option to work). \n\n"); | ||
181 | 191 | ||
182 | printf(" --overlay-clean - clean all overlays stored in $HOME/.firejail directory.\n\n"); | ||
183 | |||
184 | printf(" --overlay-tmpfs - mount a filesystem overlay on top of the current\n"); | 192 | printf(" --overlay-tmpfs - mount a filesystem overlay on top of the current\n"); |
185 | printf("\tfilesystem. The upper layer is stored in a tmpfs filesystem,\n"); | 193 | printf("\tfilesystem. The upper layer is stored in a tmpfs filesystem,\n"); |
186 | printf("\tand it is discarded when the sandbox is closed. (OverlayFS\n"); | 194 | printf("\tand it is discarded when the sandbox is closed. (OverlayFS\n"); |
187 | printf("\tsupport is required in Linux kernel for this option to work).\n\n"); | 195 | printf("\tsupport is required in Linux kernel for this option to work).\n\n"); |
188 | 196 | ||
197 | printf(" --overlay-clean - clean all overlays stored in $HOME/.firejail directory.\n\n"); | ||
198 | |||
189 | printf(" --private - mount new /root and /home/user directories in temporary\n"); | 199 | printf(" --private - mount new /root and /home/user directories in temporary\n"); |
190 | printf("\tfilesystems. All modifications are discarded when the sandbox is\n"); | 200 | printf("\tfilesystems. All modifications are discarded when the sandbox is\n"); |
191 | printf("\tclosed.\n\n"); | 201 | printf("\tclosed.\n\n"); |
diff --git a/src/man/firejail.txt b/src/man/firejail.txt index fb8cb630b..3cc9a8401 100644 --- a/src/man/firejail.txt +++ b/src/man/firejail.txt | |||
@@ -994,7 +994,7 @@ $ ls -l sandboxlog* | |||
994 | \fB\-\-overlay | 994 | \fB\-\-overlay |
995 | Mount a filesystem overlay on top of the current filesystem. Unlike the regular filesystem container, | 995 | Mount a filesystem overlay on top of the current filesystem. Unlike the regular filesystem container, |
996 | the system directories are mounted read-write. All filesystem modifications go into the overlay. | 996 | the system directories are mounted read-write. All filesystem modifications go into the overlay. |
997 | The overlay is stored in $HOME/.firejail directory. This option is not available on Grsecurity systems. | 997 | The overlay is stored in $HOME/.firejail/<PID> directory. This option is not available on Grsecurity systems. |
998 | .br | 998 | .br |
999 | 999 | ||
1000 | .br | 1000 | .br |
@@ -1008,14 +1008,40 @@ Example: | |||
1008 | $ firejail \-\-overlay firefox | 1008 | $ firejail \-\-overlay firefox |
1009 | 1009 | ||
1010 | .TP | 1010 | .TP |
1011 | \fB\-\-overlay-clean | 1011 | \fB\-\-overlay-named=name |
1012 | Clean all overlays stored in $HOME/.firejail directory. | 1012 | Mount a filesystem overlay on top of the current filesystem. Unlike the regular filesystem container, |
1013 | the system directories are mounted read-write. All filesystem modifications go into the overlay. | ||
1014 | The overlay is stored in $HOME/.firejail/<NAME> directory. The created overlay can be reused between multiple | ||
1015 | sessions. This option is not available on Grsecurity systems. | ||
1016 | .br | ||
1017 | |||
1018 | .br | ||
1019 | OverlayFS support is required in Linux kernel for this option to work. | ||
1020 | OverlayFS was officially introduced in Linux kernel version 3.18 | ||
1013 | .br | 1021 | .br |
1014 | 1022 | ||
1015 | .br | 1023 | .br |
1016 | Example: | 1024 | Example: |
1017 | .br | 1025 | .br |
1018 | $ firejail \-\-overlay-clean | 1026 | $ firejail \-\-overlay-named=jail1 firefox |
1027 | |||
1028 | .TP | ||
1029 | \fB\-\-overlay-path=path | ||
1030 | Mount a filesystem overlay on top of the current filesystem. Unlike the regular filesystem container, | ||
1031 | the system directories are mounted read-write. All filesystem modifications go into the overlay. | ||
1032 | The overlay is stored in the specified path. The created overlay can be reused between multiple sessions. | ||
1033 | This option is not available on Grsecurity systems. | ||
1034 | .br | ||
1035 | |||
1036 | .br | ||
1037 | OverlayFS support is required in Linux kernel for this option to work. | ||
1038 | OverlayFS was officially introduced in Linux kernel version 3.18 | ||
1039 | .br | ||
1040 | |||
1041 | .br | ||
1042 | Example: | ||
1043 | .br | ||
1044 | $ firejail \-\-overlay-path=~/jails/jail1 firefox | ||
1019 | 1045 | ||
1020 | .TP | 1046 | .TP |
1021 | \fB\-\-overlay-tmpfs | 1047 | \fB\-\-overlay-tmpfs |
@@ -1034,6 +1060,16 @@ Example: | |||
1034 | $ firejail \-\-overlay-tmpfs firefox | 1060 | $ firejail \-\-overlay-tmpfs firefox |
1035 | 1061 | ||
1036 | .TP | 1062 | .TP |
1063 | \fB\-\-overlay-clean | ||
1064 | Clean all overlays stored in $HOME/.firejail directory. | ||
1065 | .br | ||
1066 | |||
1067 | .br | ||
1068 | Example: | ||
1069 | .br | ||
1070 | $ firejail \-\-overlay-clean | ||
1071 | |||
1072 | .TP | ||
1037 | \fB\-\-private | 1073 | \fB\-\-private |
1038 | Mount new /root and /home/user directories in temporary | 1074 | Mount new /root and /home/user directories in temporary |
1039 | filesystems. All modifications are discarded when the sandbox is | 1075 | filesystems. All modifications are discarded when the sandbox is |