diff options
author | netblue30 <netblue30@yahoo.com> | 2016-08-16 10:11:51 -0400 |
---|---|---|
committer | GitHub <noreply@github.com> | 2016-08-16 10:11:51 -0400 |
commit | de00eb4fc27a74b09354feebe64b0385e17c5e1c (patch) | |
tree | 1869671155cbe0f1e6f9c32b7e23a61fc8093e82 /src | |
parent | overlay merge (diff) | |
parent | added more overlay options (diff) | |
download | firejail-de00eb4fc27a74b09354feebe64b0385e17c5e1c.tar.gz firejail-de00eb4fc27a74b09354feebe64b0385e17c5e1c.tar.zst firejail-de00eb4fc27a74b09354feebe64b0385e17c5e1c.zip |
Merge pull request #702 from hamzadis/overlay-changes
Added more overlay options
Diffstat (limited to 'src')
-rw-r--r-- | src/firejail/fs.c | 54 | ||||
-rw-r--r-- | src/firejail/main.c | 97 | ||||
-rw-r--r-- | src/firejail/usage.c | 18 | ||||
-rw-r--r-- | src/man/firejail.txt | 44 |
4 files changed, 172 insertions, 41 deletions
diff --git a/src/firejail/fs.c b/src/firejail/fs.c index bf78a2e3b..484b99537 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 782c9998e..8de5f9a6e 100644 --- a/src/firejail/main.c +++ b/src/firejail/main.c | |||
@@ -706,6 +706,41 @@ static void delete_x11_file(pid_t pid) { | |||
706 | free(fname); | 706 | free(fname); |
707 | } | 707 | } |
708 | 708 | ||
709 | static char *create_and_check_overlay_dir(const char *subdirname, int allow_reuse) { | ||
710 | // create ~/.firejail directory | ||
711 | struct stat s; | ||
712 | char *dirname; | ||
713 | if (asprintf(&dirname, "%s/.firejail", cfg.homedir) == -1) | ||
714 | errExit("asprintf"); | ||
715 | if (stat(dirname, &s) == -1) { | ||
716 | /* coverity[toctou] */ | ||
717 | if (mkdir(dirname, 0700)) | ||
718 | errExit("mkdir"); | ||
719 | if (chown(dirname, getuid(), getgid()) < 0) | ||
720 | errExit("chown"); | ||
721 | if (chmod(dirname, 0700) < 0) | ||
722 | errExit("chmod"); | ||
723 | } | ||
724 | else if (is_link(dirname)) { | ||
725 | fprintf(stderr, "Error: invalid ~/.firejail directory\n"); | ||
726 | exit(1); | ||
727 | } | ||
728 | |||
729 | free(dirname); | ||
730 | |||
731 | // check overlay directory | ||
732 | if (asprintf(&dirname, "%s/.firejail/%s", cfg.homedir, subdirname) == -1) | ||
733 | errExit("asprintf"); | ||
734 | if (allow_reuse == 0) { | ||
735 | if (stat(dirname, &s) == 0) { | ||
736 | fprintf(stderr, "Error: overlay directory already exists: %s\n", dirname); | ||
737 | exit(1); | ||
738 | } | ||
739 | } | ||
740 | |||
741 | return dirname; | ||
742 | } | ||
743 | |||
709 | static void detect_quiet(int argc, char **argv) { | 744 | static void detect_quiet(int argc, char **argv) { |
710 | int i; | 745 | int i; |
711 | 746 | ||
@@ -1293,34 +1328,54 @@ int main(int argc, char **argv) { | |||
1293 | arg_overlay = 1; | 1328 | arg_overlay = 1; |
1294 | arg_overlay_keep = 1; | 1329 | arg_overlay_keep = 1; |
1295 | 1330 | ||
1296 | // create ~/.firejail directory | 1331 | char *subdirname; |
1297 | char *dirname; | 1332 | if (asprintf(&subdirname, "%d", getpid()) == -1) |
1298 | if (asprintf(&dirname, "%s/.firejail", cfg.homedir) == -1) | ||
1299 | errExit("asprintf"); | 1333 | errExit("asprintf"); |
1300 | if (stat(dirname, &s) == -1) { | 1334 | cfg.overlay_dir = create_and_check_overlay_dir(subdirname, arg_overlay_reuse); |
1301 | /* coverity[toctou] */ | 1335 | |
1302 | if (mkdir(dirname, 0700)) | 1336 | free(subdirname); |
1303 | errExit("mkdir"); | 1337 | } |
1304 | if (chown(dirname, getuid(), getgid()) < 0) | 1338 | else if (strncmp(argv[i], "--overlay-named=", 16) == 0) { |
1305 | errExit("chown"); | 1339 | if (cfg.chrootdir) { |
1306 | if (chmod(dirname, 0700) < 0) | 1340 | fprintf(stderr, "Error: --overlay and --chroot options are mutually exclusive\n"); |
1307 | errExit("chmod"); | 1341 | exit(1); |
1308 | } | 1342 | } |
1309 | else if (is_link(dirname)) { | 1343 | struct stat s; |
1310 | fprintf(stderr, "Error: invalid ~/.firejail directory\n"); | 1344 | if (stat("/proc/sys/kernel/grsecurity", &s) == 0) { |
1345 | fprintf(stderr, "Error: --overlay option is not available on Grsecurity systems\n"); | ||
1311 | exit(1); | 1346 | exit(1); |
1312 | } | 1347 | } |
1348 | arg_overlay = 1; | ||
1349 | arg_overlay_keep = 1; | ||
1350 | arg_overlay_reuse = 1; | ||
1313 | 1351 | ||
1314 | free(dirname); | 1352 | char *subdirname = argv[i] + 16; |
1353 | if (subdirname == '\0') { | ||
1354 | fprintf(stderr, "Error: invalid overlay option\n"); | ||
1355 | exit(1); | ||
1356 | } | ||
1357 | cfg.overlay_dir = create_and_check_overlay_dir(subdirname, arg_overlay_reuse); | ||
1358 | } | ||
1359 | else if (strncmp(argv[i], "--overlay-path=", 15) == 0) { | ||
1360 | if (cfg.chrootdir) { | ||
1361 | fprintf(stderr, "Error: --overlay and --chroot options are mutually exclusive\n"); | ||
1362 | exit(1); | ||
1363 | } | ||
1364 | struct stat s; | ||
1365 | if (stat("/proc/sys/kernel/grsecurity", &s) == 0) { | ||
1366 | fprintf(stderr, "Error: --overlay option is not available on Grsecurity systems\n"); | ||
1367 | exit(1); | ||
1368 | } | ||
1369 | arg_overlay = 1; | ||
1370 | arg_overlay_keep = 1; | ||
1371 | arg_overlay_reuse = 1; | ||
1315 | 1372 | ||
1316 | // check overlay directory | 1373 | char *dirname = argv[i] + 15; |
1317 | if (asprintf(&dirname, "%s/.firejail/%d", cfg.homedir, getpid()) == -1) | 1374 | if (dirname == '\0') { |
1318 | errExit("asprintf"); | 1375 | fprintf(stderr, "Error: invalid overlay option\n"); |
1319 | if (stat(dirname, &s) == 0) { | ||
1320 | fprintf(stderr, "Error: overlay directory already exists: %s\n", dirname); | ||
1321 | exit(1); | 1376 | exit(1); |
1322 | } | 1377 | } |
1323 | cfg.overlay_dir = dirname; | 1378 | cfg.overlay_dir = expand_home(dirname, cfg.homedir); |
1324 | } | 1379 | } |
1325 | else if (strcmp(argv[i], "--overlay-tmpfs") == 0) { | 1380 | else if (strcmp(argv[i], "--overlay-tmpfs") == 0) { |
1326 | if (cfg.chrootdir) { | 1381 | 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 |