diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/firejail/firejail.h | 7 | ||||
-rw-r--r-- | src/firejail/fs.c | 57 | ||||
-rw-r--r-- | src/firejail/main.c | 35 | ||||
-rw-r--r-- | src/firejail/usage.c | 14 | ||||
-rw-r--r-- | src/man/firejail.txt | 21 |
5 files changed, 97 insertions, 37 deletions
diff --git a/src/firejail/firejail.h b/src/firejail/firejail.h index 18f78dd01..3acaeb6fb 100644 --- a/src/firejail/firejail.h +++ b/src/firejail/firejail.h | |||
@@ -26,7 +26,6 @@ | |||
26 | #define RO_DIR "/tmp/firejail/firejail.ro.dir" | 26 | #define RO_DIR "/tmp/firejail/firejail.ro.dir" |
27 | #define RO_FILE "/tmp/firejail/firejail.ro.file" | 27 | #define RO_FILE "/tmp/firejail/firejail.ro.file" |
28 | #define MNT_DIR "/tmp/firejail/mnt" | 28 | #define MNT_DIR "/tmp/firejail/mnt" |
29 | #define OVERLAY_DIR "/tmp/firejail/overlay" | ||
30 | #define HOME_DIR "/tmp/firejail/mnt/home" | 29 | #define HOME_DIR "/tmp/firejail/mnt/home" |
31 | #define ETC_DIR "/tmp/firejail/mnt/etc" | 30 | #define ETC_DIR "/tmp/firejail/mnt/etc" |
32 | #define MAX_INCLUDE_LEVEL 6 | 31 | #define MAX_INCLUDE_LEVEL 6 |
@@ -70,6 +69,7 @@ typedef struct config_t { | |||
70 | char *home_private_keep; // keep list for private home directory | 69 | char *home_private_keep; // keep list for private home directory |
71 | char *etc_private_keep; // keep list for private etc directory | 70 | char *etc_private_keep; // keep list for private etc directory |
72 | char *cwd; // current working directory | 71 | char *cwd; // current working directory |
72 | char *overlay_dir; | ||
73 | 73 | ||
74 | // networking | 74 | // networking |
75 | char *hostname; | 75 | char *hostname; |
@@ -109,11 +109,13 @@ static inline int any_bridge_configured(void) { | |||
109 | else | 109 | else |
110 | return 0; | 110 | return 0; |
111 | } | 111 | } |
112 | |||
112 | extern int arg_private; // mount private /home and /tmp directory | 113 | extern int arg_private; // mount private /home and /tmp directory |
113 | extern int arg_debug; // print debug messages | 114 | extern int arg_debug; // print debug messages |
114 | extern int arg_nonetwork; // --net=none | 115 | extern int arg_nonetwork; // --net=none |
115 | extern int arg_command; // -c | 116 | extern int arg_command; // -c |
116 | extern int arg_overlay; // --overlay | 117 | extern int arg_overlay; // overlay option |
118 | extern int arg_overlay_keep; // place overlay diff directory in ~/.firejail | ||
117 | extern int arg_zsh; // use zsh as default shell | 119 | extern int arg_zsh; // use zsh as default shell |
118 | extern int arg_csh; // use csh as default shell | 120 | extern int arg_csh; // use csh as default shell |
119 | 121 | ||
@@ -357,3 +359,4 @@ void fs_check_etc_list(void); | |||
357 | void fs_private_etc_list(void); | 359 | void fs_private_etc_list(void); |
358 | 360 | ||
359 | #endif | 361 | #endif |
362 | |||
diff --git a/src/firejail/fs.c b/src/firejail/fs.c index 5b8093885..c38317371 100644 --- a/src/firejail/fs.c +++ b/src/firejail/fs.c | |||
@@ -82,30 +82,6 @@ void fs_build_mnt_dir(void) { | |||
82 | } | 82 | } |
83 | } | 83 | } |
84 | 84 | ||
85 | // build /tmp/firejail/overlay directory | ||
86 | void fs_build_overlay_dir(void) { | ||
87 | struct stat s; | ||
88 | fs_build_firejail_dir(); | ||
89 | |||
90 | // create /tmp/firejail directory | ||
91 | if (stat(OVERLAY_DIR, &s)) { | ||
92 | if (arg_debug) | ||
93 | printf("Creating %s directory\n", MNT_DIR); | ||
94 | /* coverity[toctou] */ | ||
95 | int rv = mkdir(OVERLAY_DIR, S_IRWXU | S_IRWXG | S_IRWXO); | ||
96 | if (rv == -1) | ||
97 | errExit("mkdir"); | ||
98 | if (chown(OVERLAY_DIR, 0, 0) < 0) | ||
99 | errExit("chown"); | ||
100 | if (chmod(OVERLAY_DIR, S_IRWXU | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH) < 0) | ||
101 | errExit("chmod"); | ||
102 | } | ||
103 | } | ||
104 | |||
105 | |||
106 | |||
107 | |||
108 | |||
109 | //*********************************************** | 85 | //*********************************************** |
110 | // process profile file | 86 | // process profile file |
111 | //*********************************************** | 87 | //*********************************************** |
@@ -629,8 +605,25 @@ void fs_overlayfs(void) { | |||
629 | if (chmod(oroot, S_IRWXU | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH) < 0) | 605 | if (chmod(oroot, S_IRWXU | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH) < 0) |
630 | errExit("chmod"); | 606 | errExit("chmod"); |
631 | 607 | ||
608 | char *basedir = MNT_DIR; | ||
609 | if (arg_overlay_keep) { | ||
610 | // check the directory exists | ||
611 | struct stat s; | ||
612 | if (stat("/myoverlay", &s) == -1) { | ||
613 | fprintf(stderr, "Error: overlay directory should already exist\n"); | ||
614 | exit(1); | ||
615 | } | ||
616 | |||
617 | // set base for working and diff directories | ||
618 | basedir = cfg.overlay_dir; | ||
619 | if (mkdir(basedir, S_IRWXU | S_IRWXG | S_IRWXO) != 0) { | ||
620 | fprintf(stderr, "Error: cannot create overlay directory\n"); | ||
621 | exit(1); | ||
622 | } | ||
623 | } | ||
624 | |||
632 | char *odiff; | 625 | char *odiff; |
633 | if(asprintf(&odiff, "%s/odiff", MNT_DIR) == -1) | 626 | if(asprintf(&odiff, "%s/odiff", basedir) == -1) |
634 | errExit("asprintf"); | 627 | errExit("asprintf"); |
635 | if (mkdir(odiff, S_IRWXU | S_IRWXG | S_IRWXO)) | 628 | if (mkdir(odiff, S_IRWXU | S_IRWXG | S_IRWXO)) |
636 | errExit("mkdir"); | 629 | errExit("mkdir"); |
@@ -638,9 +631,9 @@ void fs_overlayfs(void) { | |||
638 | errExit("chown"); | 631 | errExit("chown"); |
639 | if (chmod(odiff, S_IRWXU | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH) < 0) | 632 | if (chmod(odiff, S_IRWXU | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH) < 0) |
640 | errExit("chmod"); | 633 | errExit("chmod"); |
641 | 634 | ||
642 | char *owork; | 635 | char *owork; |
643 | if(asprintf(&owork, "%s/owork", MNT_DIR) == -1) | 636 | if(asprintf(&owork, "%s/owork", basedir) == -1) |
644 | errExit("asprintf"); | 637 | errExit("asprintf"); |
645 | if (mkdir(owork, S_IRWXU | S_IRWXG | S_IRWXO)) | 638 | if (mkdir(owork, S_IRWXU | S_IRWXG | S_IRWXO)) |
646 | errExit("mkdir"); | 639 | errExit("mkdir"); |
@@ -648,12 +641,16 @@ void fs_overlayfs(void) { | |||
648 | errExit("chown"); | 641 | errExit("chown"); |
649 | if (chmod(owork, S_IRWXU | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH) < 0) | 642 | if (chmod(owork, S_IRWXU | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH) < 0) |
650 | errExit("chmod"); | 643 | errExit("chmod"); |
651 | 644 | ||
652 | // mount overlayfs | 645 | // mount overlayfs |
653 | if (arg_debug) | 646 | if (arg_debug) |
654 | printf("Mounting OverlayFS\n"); | 647 | printf("Mounting OverlayFS\n"); |
655 | char *option; | 648 | char *option; |
656 | if (oldkernel) { // old Ubuntu/OpenSUSE kernels | 649 | if (oldkernel) { // old Ubuntu/OpenSUSE kernels |
650 | if (arg_overlay_keep) { | ||
651 | fprintf(stderr, "Error: option --overlay= not available for kernels older than 3.18\n"); | ||
652 | exit(1); | ||
653 | } | ||
657 | if (asprintf(&option, "lowerdir=/,upperdir=%s", odiff) == -1) | 654 | if (asprintf(&option, "lowerdir=/,upperdir=%s", odiff) == -1) |
658 | errExit("asprintf"); | 655 | errExit("asprintf"); |
659 | if (mount("overlayfs", oroot, "overlayfs", MS_MGC_VAL, option) < 0) | 656 | if (mount("overlayfs", oroot, "overlayfs", MS_MGC_VAL, option) < 0) |
@@ -662,10 +659,12 @@ void fs_overlayfs(void) { | |||
662 | else { // kernel 3.18 or newer | 659 | else { // kernel 3.18 or newer |
663 | if (asprintf(&option, "lowerdir=/,upperdir=%s,workdir=%s", odiff, owork) == -1) | 660 | if (asprintf(&option, "lowerdir=/,upperdir=%s,workdir=%s", odiff, owork) == -1) |
664 | errExit("asprintf"); | 661 | errExit("asprintf"); |
662 | //printf("option #%s#\n", option); | ||
665 | if (mount("overlay", oroot, "overlay", MS_MGC_VAL, option) < 0) | 663 | if (mount("overlay", oroot, "overlay", MS_MGC_VAL, option) < 0) |
666 | errExit("mounting overlayfs"); | 664 | errExit("mounting overlayfs"); |
667 | } | 665 | } |
668 | 666 | printf("OverlayFS configured in %s directory\n", basedir); | |
667 | |||
669 | // mount-bind dev directory | 668 | // mount-bind dev directory |
670 | if (arg_debug) | 669 | if (arg_debug) |
671 | printf("Mounting /dev\n"); | 670 | printf("Mounting /dev\n"); |
diff --git a/src/firejail/main.c b/src/firejail/main.c index 6c5d9a44e..3c7a8401e 100644 --- a/src/firejail/main.c +++ b/src/firejail/main.c | |||
@@ -52,7 +52,8 @@ int arg_private = 0; // mount private /home and /tmp directoryu | |||
52 | int arg_debug = 0; // print debug messages | 52 | int arg_debug = 0; // print debug messages |
53 | int arg_nonetwork = 0; // --net=none | 53 | int arg_nonetwork = 0; // --net=none |
54 | int arg_command = 0; // -c | 54 | int arg_command = 0; // -c |
55 | int arg_overlay = 0; // --overlay | 55 | int arg_overlay = 0; // overlay option |
56 | int arg_overlay_keep = 0; // place overlay diff directory in ~/.firejail | ||
56 | int arg_zsh = 0; // use zsh as default shell | 57 | int arg_zsh = 0; // use zsh as default shell |
57 | int arg_csh = 0; // use csh as default shell | 58 | int arg_csh = 0; // use csh as default shell |
58 | 59 | ||
@@ -625,6 +626,38 @@ int main(int argc, char **argv) { | |||
625 | exit(1); | 626 | exit(1); |
626 | } | 627 | } |
627 | arg_overlay = 1; | 628 | arg_overlay = 1; |
629 | arg_overlay_keep = 1; | ||
630 | |||
631 | // create ~/.firejail directory | ||
632 | char *dirname; | ||
633 | if (asprintf(&dirname, "%s/.firejail", cfg.homedir) == -1) | ||
634 | errExit("asprintf"); | ||
635 | struct stat s; | ||
636 | if (stat(dirname, &s) == -1) { | ||
637 | if (mkdir(dirname, S_IRWXU | S_IRWXG | S_IRWXO)) | ||
638 | errExit("mkdir"); | ||
639 | if (chown(dirname, getuid(), getgid()) < 0) | ||
640 | errExit("chown"); | ||
641 | if (chmod(dirname, S_IRWXU | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH) < 0) | ||
642 | errExit("chmod"); | ||
643 | } | ||
644 | free(dirname); | ||
645 | |||
646 | // check overlay directory | ||
647 | if (asprintf(&dirname, "%s/.firejail/%d", cfg.homedir, getpid()) == -1) | ||
648 | errExit("asprintf"); | ||
649 | if (stat(dirname, &s) == 0) { | ||
650 | fprintf(stderr, "Error: overlay directory already exists: %s\n", dirname); | ||
651 | exit(1); | ||
652 | } | ||
653 | cfg.overlay_dir = dirname; | ||
654 | } | ||
655 | else if (strcmp(argv[i], "--overlay-tmpfs") == 0) { | ||
656 | if (cfg.chrootdir) { | ||
657 | fprintf(stderr, "Error: --overlay and --chroot options are mutually exclusive\n"); | ||
658 | exit(1); | ||
659 | } | ||
660 | arg_overlay = 1; | ||
628 | } | 661 | } |
629 | else if (strncmp(argv[i], "--profile=", 10) == 0) { | 662 | else if (strncmp(argv[i], "--profile=", 10) == 0) { |
630 | // multiple profile files are allowed! | 663 | // multiple profile files are allowed! |
diff --git a/src/firejail/usage.c b/src/firejail/usage.c index 3ddd85aac..9aeb5895d 100644 --- a/src/firejail/usage.c +++ b/src/firejail/usage.c | |||
@@ -140,9 +140,19 @@ void usage(void) { | |||
140 | printf("\t\tlogfile, and keep the size of the file under 500KB using log\n"); | 140 | printf("\t\tlogfile, and keep the size of the file under 500KB using log\n"); |
141 | printf("\t\trotation. Five files with prefixes .1 to .5 are used in\n"); | 141 | printf("\t\trotation. Five files with prefixes .1 to .5 are used in\n"); |
142 | printf("\t\trotation.\n\n"); | 142 | printf("\t\trotation.\n\n"); |
143 | |||
143 | printf("\t--overlay - mount a filesystem overlay on top of the current filesystem.\n"); | 144 | printf("\t--overlay - mount a filesystem overlay on top of the current filesystem.\n"); |
144 | printf("\t\t(OverlayFS support is required in Linux kernel for this option\n"); | 145 | printf("\t\tThe upper filesystem layer is persistent, and stored in\n"); |
145 | printf("\t\tto work)\n\n"); | 146 | printf("\t\t$HOME/.firejail directory. (OverlayFS support is required in\n"); |
147 | printf("\t\tLinux kernel for this option to work). \n\n"); | ||
148 | |||
149 | printf("\t--overlay-tmpfs - mount a filesystem overlay on top of the current\n"); | ||
150 | printf("\t\tfilesystem. The upper layer is stored in a tmpfs filesystem,\n"); | ||
151 | printf("\t\tand it is discarded when the sandbox is closed. (OverlayFS\n"); | ||
152 | printf("\t\tsupport is required in Linux kernel for this option to work).\n\n"); | ||
153 | |||
154 | |||
155 | |||
146 | 156 | ||
147 | printf("\t--private - mount new /root and /home/user directories in temporary\n"); | 157 | printf("\t--private - mount new /root and /home/user directories in temporary\n"); |
148 | printf("\t\tfilesystems. All modifications are discarded when the sandbox is\n"); | 158 | printf("\t\tfilesystems. All modifications are discarded when the sandbox is\n"); |
diff --git a/src/man/firejail.txt b/src/man/firejail.txt index fe2a909c9..3e399db72 100644 --- a/src/man/firejail.txt +++ b/src/man/firejail.txt | |||
@@ -602,20 +602,35 @@ $ ls -l sandboxlog* | |||
602 | 602 | ||
603 | .TP | 603 | .TP |
604 | \fB\-\-overlay | 604 | \fB\-\-overlay |
605 | Mount a filesystem overlay on top of the current filesystem. All filesystem modifications go into the overlay. | ||
606 | The overlay is stored in $HOME/.firejail directory. | ||
607 | .br | ||
608 | |||
609 | .br | ||
610 | OverlayFS support is required in Linux kernel for this option to work. | ||
611 | OverlayFS was officially introduced in Linux kernel version 3.18 | ||
612 | .br | ||
613 | |||
614 | .br | ||
615 | Example: | ||
616 | .br | ||
617 | $ firejail \-\-overlay firefox | ||
618 | |||
619 | .TP | ||
620 | \fB\-\-overlay-tmpfs | ||
605 | Mount a filesystem overlay on top of the current filesystem. All filesystem modifications go into the overlay, | 621 | Mount a filesystem overlay on top of the current filesystem. All filesystem modifications go into the overlay, |
606 | and are discarded when the sandbox is closed. | 622 | and are discarded when the sandbox is closed. |
607 | .br | 623 | .br |
608 | 624 | ||
609 | .br | 625 | .br |
610 | OverlayFS support is required in Linux kernel for this option to work. | 626 | OverlayFS support is required in Linux kernel for this option to work. |
611 | OverlayFS was officially introduced in Linux kernel version 3.18. It was also | 627 | OverlayFS was officially introduced in Linux kernel version 3.18 |
612 | available in earlier kernel versions in some distributions such as Ubuntu and OpenSUSE. | ||
613 | .br | 628 | .br |
614 | 629 | ||
615 | .br | 630 | .br |
616 | Example: | 631 | Example: |
617 | .br | 632 | .br |
618 | $ firejail \-\-overlay firefox | 633 | $ firejail \-\-overlay-tmpfs firefox |
619 | 634 | ||
620 | .TP | 635 | .TP |
621 | \fB\-\-private | 636 | \fB\-\-private |