diff options
author | netblue30 <netblue30@yahoo.com> | 2017-10-21 09:54:53 -0400 |
---|---|---|
committer | netblue30 <netblue30@yahoo.com> | 2017-10-21 09:54:53 -0400 |
commit | d6ef1d156052067b0086e08c58cd967addd23e0e (patch) | |
tree | 3bc7b9397f52e96e61c20a33c498079e8959efea | |
parent | tighten spotify profile (diff) | |
download | firejail-d6ef1d156052067b0086e08c58cd967addd23e0e.tar.gz firejail-d6ef1d156052067b0086e08c58cd967addd23e0e.tar.zst firejail-d6ef1d156052067b0086e08c58cd967addd23e0e.zip |
added whitelist support for /etc
-rw-r--r-- | src/firejail/firejail.h | 4 | ||||
-rw-r--r-- | src/firejail/fs_whitelist.c | 53 |
2 files changed, 56 insertions, 1 deletions
diff --git a/src/firejail/firejail.h b/src/firejail/firejail.h index d853daa44..387fc441c 100644 --- a/src/firejail/firejail.h +++ b/src/firejail/firejail.h | |||
@@ -81,6 +81,7 @@ | |||
81 | #define RUN_WHITELIST_DEV_DIR "/run/firejail/mnt/orig-dev" | 81 | #define RUN_WHITELIST_DEV_DIR "/run/firejail/mnt/orig-dev" |
82 | #define RUN_WHITELIST_OPT_DIR "/run/firejail/mnt/orig-opt" | 82 | #define RUN_WHITELIST_OPT_DIR "/run/firejail/mnt/orig-opt" |
83 | #define RUN_WHITELIST_SRV_DIR "/run/firejail/mnt/orig-srv" | 83 | #define RUN_WHITELIST_SRV_DIR "/run/firejail/mnt/orig-srv" |
84 | #define RUN_WHITELIST_ETC_DIR "/run/firejail/mnt/orig-etc" | ||
84 | 85 | ||
85 | #define RUN_XAUTHORITY_FILE "/run/firejail/mnt/.Xauthority" | 86 | #define RUN_XAUTHORITY_FILE "/run/firejail/mnt/.Xauthority" |
86 | #define RUN_XAUTHORITY_SEC_FILE "/run/firejail/mnt/sec.Xauthority" | 87 | #define RUN_XAUTHORITY_SEC_FILE "/run/firejail/mnt/sec.Xauthority" |
@@ -197,7 +198,8 @@ typedef struct profile_entry_t { | |||
197 | unsigned var_dir:1; // whitelist in /var directory | 198 | unsigned var_dir:1; // whitelist in /var directory |
198 | unsigned dev_dir:1; // whitelist in /dev directory | 199 | unsigned dev_dir:1; // whitelist in /dev directory |
199 | unsigned opt_dir:1; // whitelist in /opt directory | 200 | unsigned opt_dir:1; // whitelist in /opt directory |
200 | unsigned srv_dir:1; // whitelist in /srv directory | 201 | unsigned srv_dir:1; // whitelist in /srv directory |
202 | unsigned etc_dir:1; // whitelist in /etc directory | ||
201 | }ProfileEntry; | 203 | }ProfileEntry; |
202 | 204 | ||
203 | typedef struct config_t { | 205 | typedef struct config_t { |
diff --git a/src/firejail/fs_whitelist.c b/src/firejail/fs_whitelist.c index bfc773374..0ae5a7155 100644 --- a/src/firejail/fs_whitelist.c +++ b/src/firejail/fs_whitelist.c | |||
@@ -257,6 +257,15 @@ static void whitelist_path(ProfileEntry *entry) { | |||
257 | if (asprintf(&wfile, "%s/%s", RUN_WHITELIST_SRV_DIR, fname) == -1) | 257 | if (asprintf(&wfile, "%s/%s", RUN_WHITELIST_SRV_DIR, fname) == -1) |
258 | errExit("asprintf"); | 258 | errExit("asprintf"); |
259 | } | 259 | } |
260 | else if (entry->etc_dir) { | ||
261 | fname = path + 4; // strlen("/etc") | ||
262 | if (*fname == '\0') | ||
263 | goto errexit; | ||
264 | |||
265 | if (asprintf(&wfile, "%s/%s", RUN_WHITELIST_ETC_DIR, fname) == -1) | ||
266 | errExit("asprintf"); | ||
267 | } | ||
268 | |||
260 | // check if the file exists | 269 | // check if the file exists |
261 | struct stat s; | 270 | struct stat s; |
262 | if (wfile && stat(wfile, &s) == 0) { | 271 | if (wfile && stat(wfile, &s) == 0) { |
@@ -325,6 +334,7 @@ void fs_whitelist(void) { | |||
325 | int dev_dir = 0; // /dev directory flag | 334 | int dev_dir = 0; // /dev directory flag |
326 | int opt_dir = 0; // /opt directory flag | 335 | int opt_dir = 0; // /opt directory flag |
327 | int srv_dir = 0; // /srv directory flag | 336 | int srv_dir = 0; // /srv directory flag |
337 | int etc_dir = 0; // /etc directory flag | ||
328 | 338 | ||
329 | size_t nowhitelist_c = 0; | 339 | size_t nowhitelist_c = 0; |
330 | size_t nowhitelist_m = 32; | 340 | size_t nowhitelist_m = 32; |
@@ -414,6 +424,8 @@ void fs_whitelist(void) { | |||
414 | opt_dir = 1; | 424 | opt_dir = 1; |
415 | else if (strncmp(new_name, "/srv/", 5) == 0) | 425 | else if (strncmp(new_name, "/srv/", 5) == 0) |
416 | srv_dir = 1; | 426 | srv_dir = 1; |
427 | else if (strncmp(new_name, "/etc/", 5) == 0) | ||
428 | etc_dir = 1; | ||
417 | } | 429 | } |
418 | 430 | ||
419 | entry->data = EMPTY_STRING; | 431 | entry->data = EMPTY_STRING; |
@@ -533,6 +545,19 @@ void fs_whitelist(void) { | |||
533 | goto errexit; | 545 | goto errexit; |
534 | } | 546 | } |
535 | } | 547 | } |
548 | else if (strncmp(new_name, "/etc/", 5) == 0) { | ||
549 | entry->etc_dir = 1; | ||
550 | etc_dir = 1; | ||
551 | // special handling for some of the symlinks | ||
552 | if (strcmp(new_name, "/etc/localtime") == 0); | ||
553 | else if (strcmp(new_name, "/etc/mtab") == 0); | ||
554 | else if (strcmp(new_name, "/etc/os-release") == 0); | ||
555 | // both path and absolute path are under /etc | ||
556 | else { | ||
557 | if (strncmp(fname, "/etc/", 5) != 0) | ||
558 | goto errexit; | ||
559 | } | ||
560 | } | ||
536 | else { | 561 | else { |
537 | goto errexit; | 562 | goto errexit; |
538 | } | 563 | } |
@@ -718,6 +743,27 @@ void fs_whitelist(void) { | |||
718 | srv_dir = 0; | 743 | srv_dir = 0; |
719 | } | 744 | } |
720 | 745 | ||
746 | // /etc mountpoint | ||
747 | if (etc_dir) { | ||
748 | // check if /etc directory exists | ||
749 | struct stat s; | ||
750 | if (stat("/etc", &s) == 0) { | ||
751 | // keep a copy of real /etc directory in RUN_WHITELIST_ETC_DIR | ||
752 | mkdir_attr(RUN_WHITELIST_ETC_DIR, 0755, 0, 0); | ||
753 | if (mount("/etc", RUN_WHITELIST_ETC_DIR, NULL, MS_BIND|MS_REC, NULL) < 0) | ||
754 | errExit("mount bind"); | ||
755 | |||
756 | // mount tmpfs on /srv | ||
757 | if (arg_debug || arg_debug_whitelists) | ||
758 | printf("Mounting tmpfs on /etc directory\n"); | ||
759 | if (mount("tmpfs", "/etc", "tmpfs", MS_NOSUID | MS_STRICTATIME | MS_REC, "mode=755,gid=0") < 0) | ||
760 | errExit("mounting tmpfs on /etc"); | ||
761 | fs_logger("tmpfs /etc"); | ||
762 | } | ||
763 | else | ||
764 | etc_dir = 0; | ||
765 | } | ||
766 | |||
721 | 767 | ||
722 | // go through profile rules again, and interpret whitelist commands | 768 | // go through profile rules again, and interpret whitelist commands |
723 | entry = cfg.profile; | 769 | entry = cfg.profile; |
@@ -817,6 +863,13 @@ void fs_whitelist(void) { | |||
817 | fs_logger2("tmpfs", RUN_WHITELIST_SRV_DIR); | 863 | fs_logger2("tmpfs", RUN_WHITELIST_SRV_DIR); |
818 | } | 864 | } |
819 | 865 | ||
866 | // mask the real /etc directory, currently mounted on RUN_WHITELIST_ETC_DIR | ||
867 | if (etc_dir) { | ||
868 | if (mount("tmpfs", RUN_WHITELIST_ETC_DIR, "tmpfs", MS_NOSUID | MS_STRICTATIME | MS_REC, "mode=755,gid=0") < 0) | ||
869 | errExit("mount tmpfs"); | ||
870 | fs_logger2("tmpfs", RUN_WHITELIST_ETC_DIR); | ||
871 | } | ||
872 | |||
820 | if (new_name) | 873 | if (new_name) |
821 | free(new_name); | 874 | free(new_name); |
822 | 875 | ||