diff options
author | Aleksey Manevich <manevich.aleksey@gmail.com> | 2016-09-15 19:59:20 +0300 |
---|---|---|
committer | Aleksey Manevich <manevich.aleksey@gmail.com> | 2016-09-15 21:16:49 +0300 |
commit | 30c9afe1085e8780f16e606a07f6381f7b47d108 (patch) | |
tree | a844d37fe9609840a3897fba5fd17e6bbfba4260 /src | |
parent | testing (diff) | |
download | firejail-30c9afe1085e8780f16e606a07f6381f7b47d108.tar.gz firejail-30c9afe1085e8780f16e606a07f6381f7b47d108.tar.zst firejail-30c9afe1085e8780f16e606a07f6381f7b47d108.zip |
/mnt whitelisting
Diffstat (limited to 'src')
-rw-r--r-- | src/firejail/firejail.h | 2 | ||||
-rw-r--r-- | src/firejail/fs_whitelist.c | 59 |
2 files changed, 61 insertions, 0 deletions
diff --git a/src/firejail/firejail.h b/src/firejail/firejail.h index ed9d901c0..7043aa0ca 100644 --- a/src/firejail/firejail.h +++ b/src/firejail/firejail.h | |||
@@ -55,6 +55,7 @@ | |||
55 | #define RUN_WHITELIST_HOME_USER_DIR "/run/firejail/mnt/orig-home-user" // home directory whitelisting | 55 | #define RUN_WHITELIST_HOME_USER_DIR "/run/firejail/mnt/orig-home-user" // home directory whitelisting |
56 | #define RUN_WHITELIST_TMP_DIR "/run/firejail/mnt/orig-tmp" | 56 | #define RUN_WHITELIST_TMP_DIR "/run/firejail/mnt/orig-tmp" |
57 | #define RUN_WHITELIST_MEDIA_DIR "/run/firejail/mnt/orig-media" | 57 | #define RUN_WHITELIST_MEDIA_DIR "/run/firejail/mnt/orig-media" |
58 | #define RUN_WHITELIST_MNT_DIR "/run/firejail/mnt/orig-mnt" | ||
58 | #define RUN_WHITELIST_VAR_DIR "/run/firejail/mnt/orig-var" | 59 | #define RUN_WHITELIST_VAR_DIR "/run/firejail/mnt/orig-var" |
59 | #define RUN_WHITELIST_DEV_DIR "/run/firejail/mnt/orig-dev" | 60 | #define RUN_WHITELIST_DEV_DIR "/run/firejail/mnt/orig-dev" |
60 | #define RUN_WHITELIST_OPT_DIR "/run/firejail/mnt/orig-opt" | 61 | #define RUN_WHITELIST_OPT_DIR "/run/firejail/mnt/orig-opt" |
@@ -164,6 +165,7 @@ typedef struct profile_entry_t { | |||
164 | unsigned home_dir:1; // whitelist in /home/user directory | 165 | unsigned home_dir:1; // whitelist in /home/user directory |
165 | unsigned tmp_dir:1; // whitelist in /tmp directory | 166 | unsigned tmp_dir:1; // whitelist in /tmp directory |
166 | unsigned media_dir:1; // whitelist in /media directory | 167 | unsigned media_dir:1; // whitelist in /media directory |
168 | unsigned mnt_dir:1; // whitelist in /mnt directory | ||
167 | unsigned var_dir:1; // whitelist in /var directory | 169 | unsigned var_dir:1; // whitelist in /var directory |
168 | unsigned dev_dir:1; // whitelist in /dev directory | 170 | unsigned dev_dir:1; // whitelist in /dev directory |
169 | unsigned opt_dir:1; // whitelist in /opt directory | 171 | unsigned opt_dir:1; // whitelist in /opt directory |
diff --git a/src/firejail/fs_whitelist.c b/src/firejail/fs_whitelist.c index 11e626b6e..ad7fea227 100644 --- a/src/firejail/fs_whitelist.c +++ b/src/firejail/fs_whitelist.c | |||
@@ -214,6 +214,16 @@ static void whitelist_path(ProfileEntry *entry) { | |||
214 | if (asprintf(&wfile, "%s/%s", RUN_WHITELIST_MEDIA_DIR, fname) == -1) | 214 | if (asprintf(&wfile, "%s/%s", RUN_WHITELIST_MEDIA_DIR, fname) == -1) |
215 | errExit("asprintf"); | 215 | errExit("asprintf"); |
216 | } | 216 | } |
217 | else if (entry->mnt_dir) { | ||
218 | fname = path + 4; // strlen("/mnt") | ||
219 | if (*fname == '\0') { | ||
220 | fprintf(stderr, "Error: file %s is not in /mnt directory, exiting...\n", path); | ||
221 | exit(1); | ||
222 | } | ||
223 | |||
224 | if (asprintf(&wfile, "%s/%s", RUN_WHITELIST_MNT_DIR, fname) == -1) | ||
225 | errExit("asprintf"); | ||
226 | } | ||
217 | else if (entry->var_dir) { | 227 | else if (entry->var_dir) { |
218 | fname = path + 4; // strlen("/var") | 228 | fname = path + 4; // strlen("/var") |
219 | if (*fname == '\0') { | 229 | if (*fname == '\0') { |
@@ -303,6 +313,7 @@ void fs_whitelist(void) { | |||
303 | int home_dir = 0; // /home/user directory flag | 313 | int home_dir = 0; // /home/user directory flag |
304 | int tmp_dir = 0; // /tmp directory flag | 314 | int tmp_dir = 0; // /tmp directory flag |
305 | int media_dir = 0; // /media directory flag | 315 | int media_dir = 0; // /media directory flag |
316 | int mnt_dir = 0; // /mnt directory flag | ||
306 | int var_dir = 0; // /var directory flag | 317 | int var_dir = 0; // /var directory flag |
307 | int dev_dir = 0; // /dev directory flag | 318 | int dev_dir = 0; // /dev directory flag |
308 | int opt_dir = 0; // /opt directory flag | 319 | int opt_dir = 0; // /opt directory flag |
@@ -368,6 +379,8 @@ void fs_whitelist(void) { | |||
368 | tmp_dir = 1; | 379 | tmp_dir = 1; |
369 | else if (strncmp(new_name, "/media/", 7) == 0) | 380 | else if (strncmp(new_name, "/media/", 7) == 0) |
370 | media_dir = 1; | 381 | media_dir = 1; |
382 | else if (strncmp(new_name, "/mnt/", 5) == 0) | ||
383 | mnt_dir = 1; | ||
371 | else if (strncmp(new_name, "/var/", 5) == 0) | 384 | else if (strncmp(new_name, "/var/", 5) == 0) |
372 | var_dir = 1; | 385 | var_dir = 1; |
373 | else if (strncmp(new_name, "/dev/", 5) == 0) | 386 | else if (strncmp(new_name, "/dev/", 5) == 0) |
@@ -423,6 +436,16 @@ void fs_whitelist(void) { | |||
423 | goto errexit; | 436 | goto errexit; |
424 | } | 437 | } |
425 | } | 438 | } |
439 | else if (strncmp(new_name, "/mnt/", 5) == 0) { | ||
440 | entry->mnt_dir = 1; | ||
441 | mnt_dir = 1; | ||
442 | // both path and absolute path are under /mnt | ||
443 | if (strncmp(fname, "/mnt/", 5) != 0) { | ||
444 | if (arg_debug) | ||
445 | fprintf(stderr, "Debug %d: fname #%s#\n", __LINE__, fname); | ||
446 | goto errexit; | ||
447 | } | ||
448 | } | ||
426 | else if (strncmp(new_name, "/var/", 5) == 0) { | 449 | else if (strncmp(new_name, "/var/", 5) == 0) { |
427 | entry->var_dir = 1; | 450 | entry->var_dir = 1; |
428 | var_dir = 1; | 451 | var_dir = 1; |
@@ -580,6 +603,35 @@ void fs_whitelist(void) { | |||
580 | media_dir = 0; | 603 | media_dir = 0; |
581 | } | 604 | } |
582 | 605 | ||
606 | // /mnt mountpoint | ||
607 | if (mnt_dir) { | ||
608 | // check if /mnt directory exists | ||
609 | struct stat s; | ||
610 | if (stat("/mnt", &s) == 0) { | ||
611 | // keep a copy of real /mnt directory in RUN_WHITELIST_MNT_DIR | ||
612 | int rv = mkdir(RUN_WHITELIST_MNT_DIR, 0755); | ||
613 | if (rv == -1) | ||
614 | errExit("mkdir"); | ||
615 | if (chown(RUN_WHITELIST_MNT_DIR, 0, 0) < 0) | ||
616 | errExit("chown"); | ||
617 | if (chmod(RUN_WHITELIST_MNT_DIR, 0755) < 0) | ||
618 | errExit("chmod"); | ||
619 | |||
620 | if (mount("/mnt", RUN_WHITELIST_MNT_DIR, NULL, MS_BIND|MS_REC, NULL) < 0) | ||
621 | errExit("mount bind"); | ||
622 | |||
623 | // mount tmpfs on /mnt | ||
624 | if (arg_debug || arg_debug_whitelists) | ||
625 | printf("Mounting tmpfs on /mnt directory\n"); | ||
626 | if (mount("tmpfs", "/mnt", "tmpfs", MS_NOSUID | MS_STRICTATIME | MS_REC, "mode=755,gid=0") < 0) | ||
627 | errExit("mounting tmpfs on /mnt"); | ||
628 | fs_logger("tmpfs /mnt"); | ||
629 | } | ||
630 | else | ||
631 | mnt_dir = 0; | ||
632 | } | ||
633 | |||
634 | |||
583 | // /var mountpoint | 635 | // /var mountpoint |
584 | if (var_dir) { | 636 | if (var_dir) { |
585 | // keep a copy of real /var directory in RUN_WHITELIST_VAR_DIR | 637 | // keep a copy of real /var directory in RUN_WHITELIST_VAR_DIR |
@@ -730,6 +782,13 @@ void fs_whitelist(void) { | |||
730 | fs_logger2("tmpfs", RUN_WHITELIST_MEDIA_DIR); | 782 | fs_logger2("tmpfs", RUN_WHITELIST_MEDIA_DIR); |
731 | } | 783 | } |
732 | 784 | ||
785 | // mask the real /mnt directory, currently mounted on RUN_WHITELIST_MNT_DIR | ||
786 | if (mnt_dir) { | ||
787 | if (mount("tmpfs", RUN_WHITELIST_MNT_DIR, "tmpfs", MS_NOSUID | MS_STRICTATIME | MS_REC, "mode=755,gid=0") < 0) | ||
788 | errExit("mount tmpfs"); | ||
789 | fs_logger2("tmpfs", RUN_WHITELIST_MNT_DIR); | ||
790 | } | ||
791 | |||
733 | if (new_name) | 792 | if (new_name) |
734 | free(new_name); | 793 | free(new_name); |
735 | 794 | ||