summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorLibravatar RD Projekt <info@rdprojekt.pl>2018-05-08 16:24:16 +0200
committerLibravatar RDP <info@rdprojekt.pl>2018-05-09 12:37:35 +0200
commit95c8e284d05a2ff3eb673dcd8ee6115d27fe1225 (patch)
tree3ec574616e369a4ab7372efb6ad4776cb011b9da /src
parentlower some more privs (diff)
downloadfirejail-95c8e284d05a2ff3eb673dcd8ee6115d27fe1225.tar.gz
firejail-95c8e284d05a2ff3eb673dcd8ee6115d27fe1225.tar.zst
firejail-95c8e284d05a2ff3eb673dcd8ee6115d27fe1225.zip
Allow accessing /sys/module directory
It is required for example by Blender, which Firejail supports. Blender needs read-only access to /sys/module/amdgpu in order to use AMD card with OpenCL. Now user can allow such access by specifying: noblacklist /sys/module whitelist /sys/module/amdgpu read-only /sys/module/amdgpu
Diffstat (limited to 'src')
-rw-r--r--src/firejail/firejail.h2
-rw-r--r--src/firejail/fs.c4
-rw-r--r--src/firejail/fs_whitelist.c46
3 files changed, 50 insertions, 2 deletions
diff --git a/src/firejail/firejail.h b/src/firejail/firejail.h
index 8c0b3ba4e..efc0dfd8d 100644
--- a/src/firejail/firejail.h
+++ b/src/firejail/firejail.h
@@ -85,6 +85,7 @@
85#define RUN_WHITELIST_SRV_DIR "/run/firejail/mnt/orig-srv" 85#define RUN_WHITELIST_SRV_DIR "/run/firejail/mnt/orig-srv"
86#define RUN_WHITELIST_ETC_DIR "/run/firejail/mnt/orig-etc" 86#define RUN_WHITELIST_ETC_DIR "/run/firejail/mnt/orig-etc"
87#define RUN_WHITELIST_SHARE_DIR "/run/firejail/mnt/orig-share" 87#define RUN_WHITELIST_SHARE_DIR "/run/firejail/mnt/orig-share"
88#define RUN_WHITELIST_MODULE_DIR "/run/firejail/mnt/orig-module"
88 89
89#define RUN_XAUTHORITY_FILE "/run/firejail/mnt/.Xauthority" 90#define RUN_XAUTHORITY_FILE "/run/firejail/mnt/.Xauthority"
90#define RUN_XAUTHORITY_SEC_FILE "/run/firejail/mnt/sec.Xauthority" 91#define RUN_XAUTHORITY_SEC_FILE "/run/firejail/mnt/sec.Xauthority"
@@ -204,6 +205,7 @@ typedef struct profile_entry_t {
204 unsigned srv_dir:1; // whitelist in /srv directory 205 unsigned srv_dir:1; // whitelist in /srv directory
205 unsigned etc_dir:1; // whitelist in /etc directory 206 unsigned etc_dir:1; // whitelist in /etc directory
206 unsigned share_dir:1; // whitelist in /usr/share directory 207 unsigned share_dir:1; // whitelist in /usr/share directory
208 unsigned module_dir:1; // whitelist in /sys/module directory
207}ProfileEntry; 209}ProfileEntry;
208 210
209typedef struct config_t { 211typedef struct config_t {
diff --git a/src/firejail/fs.c b/src/firejail/fs.c
index 88f92ad74..ea0631da5 100644
--- a/src/firejail/fs.c
+++ b/src/firejail/fs.c
@@ -565,12 +565,12 @@ void fs_proc_sys_dev_boot(void) {
565 565
566 disable_file(BLACKLIST_FILE, "/sys/firmware"); 566 disable_file(BLACKLIST_FILE, "/sys/firmware");
567 disable_file(BLACKLIST_FILE, "/sys/hypervisor"); 567 disable_file(BLACKLIST_FILE, "/sys/hypervisor");
568 { // allow user access to /sys/fs if "--noblacklist=/sys/fs" is present on the command line 568 { // allow user access to some directories in /sys/ by specifying 'noblacklist' option
569 EUID_USER(); 569 EUID_USER();
570 profile_add("blacklist /sys/fs"); 570 profile_add("blacklist /sys/fs");
571 profile_add("blacklist /sys/module");
571 EUID_ROOT(); 572 EUID_ROOT();
572 } 573 }
573 disable_file(BLACKLIST_FILE, "/sys/module");
574 disable_file(BLACKLIST_FILE, "/sys/power"); 574 disable_file(BLACKLIST_FILE, "/sys/power");
575 disable_file(BLACKLIST_FILE, "/sys/kernel/debug"); 575 disable_file(BLACKLIST_FILE, "/sys/kernel/debug");
576 disable_file(BLACKLIST_FILE, "/sys/kernel/vmcoreinfo"); 576 disable_file(BLACKLIST_FILE, "/sys/kernel/vmcoreinfo");
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