diff options
Diffstat (limited to 'src/firejail/fs_whitelist.c')
-rw-r--r-- | src/firejail/fs_whitelist.c | 46 |
1 files changed, 46 insertions, 0 deletions
diff --git a/src/firejail/fs_whitelist.c b/src/firejail/fs_whitelist.c index b1b30cd5e..9ef80e5c3 100644 --- a/src/firejail/fs_whitelist.c +++ b/src/firejail/fs_whitelist.c | |||
@@ -283,6 +283,14 @@ static void whitelist_path(ProfileEntry *entry) { | |||
283 | if (asprintf(&wfile, "%s/%s", RUN_WHITELIST_SHARE_DIR, fname) == -1) | 283 | if (asprintf(&wfile, "%s/%s", RUN_WHITELIST_SHARE_DIR, fname) == -1) |
284 | errExit("asprintf"); | 284 | errExit("asprintf"); |
285 | } | 285 | } |
286 | else if (entry->module_dir) { | ||
287 | fname = path + 12; // strlen("/sys/module/") | ||
288 | if (*fname == '\0') | ||
289 | goto errexit; | ||
290 | |||
291 | if (asprintf(&wfile, "%s/%s", RUN_WHITELIST_MODULE_DIR, fname) == -1) | ||
292 | errExit("asprintf"); | ||
293 | } | ||
286 | 294 | ||
287 | // check if the file exists | 295 | // check if the file exists |
288 | assert(wfile); | 296 | assert(wfile); |
@@ -365,6 +373,7 @@ void fs_whitelist(void) { | |||
365 | int srv_dir = 0; // /srv directory flag | 373 | int srv_dir = 0; // /srv directory flag |
366 | int etc_dir = 0; // /etc directory flag | 374 | int etc_dir = 0; // /etc directory flag |
367 | int share_dir = 0; // /usr/share directory flag | 375 | int share_dir = 0; // /usr/share directory flag |
376 | int module_dir = 0; // /sys/module directory flag | ||
368 | 377 | ||
369 | size_t nowhitelist_c = 0; | 378 | size_t nowhitelist_c = 0; |
370 | size_t nowhitelist_m = 32; | 379 | size_t nowhitelist_m = 32; |
@@ -471,6 +480,8 @@ void fs_whitelist(void) { | |||
471 | etc_dir = 1; | 480 | etc_dir = 1; |
472 | else if (strncmp(new_name, "/usr/share/", 11) == 0) | 481 | else if (strncmp(new_name, "/usr/share/", 11) == 0) |
473 | share_dir = 1; | 482 | share_dir = 1; |
483 | else if (strncmp(new_name, "/sys/module/", 12) == 0) | ||
484 | module_dir = 1; | ||
474 | } | 485 | } |
475 | 486 | ||
476 | entry->data = EMPTY_STRING; | 487 | entry->data = EMPTY_STRING; |
@@ -618,6 +629,13 @@ void fs_whitelist(void) { | |||
618 | if (strncmp(fname, "/usr/share/", 11) != 0) | 629 | if (strncmp(fname, "/usr/share/", 11) != 0) |
619 | goto errexit; | 630 | goto errexit; |
620 | } | 631 | } |
632 | else if (strncmp(new_name, "/sys/module/", 12) == 0) { | ||
633 | entry->module_dir = 1; | ||
634 | module_dir = 1; | ||
635 | // both path and absolute path are under /sys/module | ||
636 | if (strncmp(fname, "/sys/module/", 12) != 0) | ||
637 | goto errexit; | ||
638 | } | ||
621 | else { | 639 | else { |
622 | goto errexit; | 640 | goto errexit; |
623 | } | 641 | } |
@@ -846,6 +864,27 @@ void fs_whitelist(void) { | |||
846 | share_dir = 0; | 864 | share_dir = 0; |
847 | } | 865 | } |
848 | 866 | ||
867 | // /sys/module mountpoint | ||
868 | if (module_dir) { | ||
869 | // check if /sys/module directory exists | ||
870 | struct stat s; | ||
871 | if (stat("/sys/module", &s) == 0) { | ||
872 | // keep a copy of real /sys/module directory in RUN_WHITELIST_MODULE_DIR | ||
873 | mkdir_attr(RUN_WHITELIST_MODULE_DIR, 0755, 0, 0); | ||
874 | if (mount("/sys/module", RUN_WHITELIST_MODULE_DIR, NULL, MS_BIND|MS_REC, NULL) < 0) | ||
875 | errExit("mount bind"); | ||
876 | |||
877 | // mount tmpfs on /sys/module | ||
878 | if (arg_debug || arg_debug_whitelists) | ||
879 | printf("Mounting tmpfs on /sys/module directory\n"); | ||
880 | if (mount("tmpfs", "/sys/module", "tmpfs", MS_NOSUID | MS_STRICTATIME | MS_REC, "mode=755,gid=0") < 0) | ||
881 | errExit("mounting tmpfs on /sys/module"); | ||
882 | fs_logger("tmpfs /sys/module"); | ||
883 | } | ||
884 | else | ||
885 | module_dir = 0; | ||
886 | } | ||
887 | |||
849 | 888 | ||
850 | // go through profile rules again, and interpret whitelist commands | 889 | // go through profile rules again, and interpret whitelist commands |
851 | entry = cfg.profile; | 890 | entry = cfg.profile; |
@@ -967,6 +1006,13 @@ void fs_whitelist(void) { | |||
967 | fs_logger2("tmpfs", RUN_WHITELIST_SHARE_DIR); | 1006 | fs_logger2("tmpfs", RUN_WHITELIST_SHARE_DIR); |
968 | } | 1007 | } |
969 | 1008 | ||
1009 | // mask the real /sys/module directory, currently mounted on RUN_WHITELIST_MODULE_DIR | ||
1010 | if (module_dir) { | ||
1011 | if (mount("tmpfs", RUN_WHITELIST_MODULE_DIR, "tmpfs", MS_NOSUID | MS_STRICTATIME | MS_REC, "mode=755,gid=0") < 0) | ||
1012 | errExit("mount tmpfs"); | ||
1013 | fs_logger2("tmpfs", RUN_WHITELIST_MODULE_DIR); | ||
1014 | } | ||
1015 | |||
970 | if (new_name) | 1016 | if (new_name) |
971 | free(new_name); | 1017 | free(new_name); |
972 | 1018 | ||