Skip to content

Commit

Permalink
Allow accessing /sys/module directory
Browse files Browse the repository at this point in the history
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
  • Loading branch information
RDProjekt committed May 9, 2018
1 parent 6dd512c commit 95c8e28
Show file tree
Hide file tree
Showing 3 changed files with 50 additions and 2 deletions.
2 changes: 2 additions & 0 deletions src/firejail/firejail.h
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,7 @@
#define RUN_WHITELIST_SRV_DIR "/run/firejail/mnt/orig-srv"
#define RUN_WHITELIST_ETC_DIR "/run/firejail/mnt/orig-etc"
#define RUN_WHITELIST_SHARE_DIR "/run/firejail/mnt/orig-share"
#define RUN_WHITELIST_MODULE_DIR "/run/firejail/mnt/orig-module"

#define RUN_XAUTHORITY_FILE "/run/firejail/mnt/.Xauthority"
#define RUN_XAUTHORITY_SEC_FILE "/run/firejail/mnt/sec.Xauthority"
Expand Down Expand Up @@ -204,6 +205,7 @@ typedef struct profile_entry_t {
unsigned srv_dir:1; // whitelist in /srv directory
unsigned etc_dir:1; // whitelist in /etc directory
unsigned share_dir:1; // whitelist in /usr/share directory
unsigned module_dir:1; // whitelist in /sys/module directory
}ProfileEntry;

typedef struct config_t {
Expand Down
4 changes: 2 additions & 2 deletions src/firejail/fs.c
Original file line number Diff line number Diff line change
Expand Up @@ -565,12 +565,12 @@ void fs_proc_sys_dev_boot(void) {

disable_file(BLACKLIST_FILE, "/sys/firmware");
disable_file(BLACKLIST_FILE, "/sys/hypervisor");
{ // allow user access to /sys/fs if "--noblacklist=/sys/fs" is present on the command line
{ // allow user access to some directories in /sys/ by specifying 'noblacklist' option
EUID_USER();
profile_add("blacklist /sys/fs");
profile_add("blacklist /sys/module");
EUID_ROOT();
}
disable_file(BLACKLIST_FILE, "/sys/module");
disable_file(BLACKLIST_FILE, "/sys/power");
disable_file(BLACKLIST_FILE, "/sys/kernel/debug");
disable_file(BLACKLIST_FILE, "/sys/kernel/vmcoreinfo");
Expand Down
46 changes: 46 additions & 0 deletions src/firejail/fs_whitelist.c
Original file line number Diff line number Diff line change
Expand Up @@ -283,6 +283,14 @@ static void whitelist_path(ProfileEntry *entry) {
if (asprintf(&wfile, "%s/%s", RUN_WHITELIST_SHARE_DIR, fname) == -1)
errExit("asprintf");
}
else if (entry->module_dir) {
fname = path + 12; // strlen("/sys/module/")
if (*fname == '\0')
goto errexit;

if (asprintf(&wfile, "%s/%s", RUN_WHITELIST_MODULE_DIR, fname) == -1)
errExit("asprintf");
}

// check if the file exists
assert(wfile);
Expand Down Expand Up @@ -365,6 +373,7 @@ void fs_whitelist(void) {
int srv_dir = 0; // /srv directory flag
int etc_dir = 0; // /etc directory flag
int share_dir = 0; // /usr/share directory flag
int module_dir = 0; // /sys/module directory flag

size_t nowhitelist_c = 0;
size_t nowhitelist_m = 32;
Expand Down Expand Up @@ -471,6 +480,8 @@ void fs_whitelist(void) {
etc_dir = 1;
else if (strncmp(new_name, "/usr/share/", 11) == 0)
share_dir = 1;
else if (strncmp(new_name, "/sys/module/", 12) == 0)
module_dir = 1;
}

entry->data = EMPTY_STRING;
Expand Down Expand Up @@ -618,6 +629,13 @@ void fs_whitelist(void) {
if (strncmp(fname, "/usr/share/", 11) != 0)
goto errexit;
}
else if (strncmp(new_name, "/sys/module/", 12) == 0) {
entry->module_dir = 1;
module_dir = 1;
// both path and absolute path are under /sys/module
if (strncmp(fname, "/sys/module/", 12) != 0)
goto errexit;
}
else {
goto errexit;
}
Expand Down Expand Up @@ -846,6 +864,27 @@ void fs_whitelist(void) {
share_dir = 0;
}

// /sys/module mountpoint
if (module_dir) {
// check if /sys/module directory exists
struct stat s;
if (stat("/sys/module", &s) == 0) {
// keep a copy of real /sys/module directory in RUN_WHITELIST_MODULE_DIR
mkdir_attr(RUN_WHITELIST_MODULE_DIR, 0755, 0, 0);
if (mount("/sys/module", RUN_WHITELIST_MODULE_DIR, NULL, MS_BIND|MS_REC, NULL) < 0)
errExit("mount bind");

// mount tmpfs on /sys/module
if (arg_debug || arg_debug_whitelists)
printf("Mounting tmpfs on /sys/module directory\n");
if (mount("tmpfs", "/sys/module", "tmpfs", MS_NOSUID | MS_STRICTATIME | MS_REC, "mode=755,gid=0") < 0)
errExit("mounting tmpfs on /sys/module");
fs_logger("tmpfs /sys/module");
}
else
module_dir = 0;
}


// go through profile rules again, and interpret whitelist commands
entry = cfg.profile;
Expand Down Expand Up @@ -967,6 +1006,13 @@ void fs_whitelist(void) {
fs_logger2("tmpfs", RUN_WHITELIST_SHARE_DIR);
}

// mask the real /sys/module directory, currently mounted on RUN_WHITELIST_MODULE_DIR
if (module_dir) {
if (mount("tmpfs", RUN_WHITELIST_MODULE_DIR, "tmpfs", MS_NOSUID | MS_STRICTATIME | MS_REC, "mode=755,gid=0") < 0)
errExit("mount tmpfs");
fs_logger2("tmpfs", RUN_WHITELIST_MODULE_DIR);
}

if (new_name)
free(new_name);

Expand Down

0 comments on commit 95c8e28

Please sign in to comment.