From 2d2ca4359dd265d40b01eaf1d4401b2839a7e7ed Mon Sep 17 00:00:00 2001 From: netblue30 Date: Sat, 21 Nov 2015 16:31:47 -0500 Subject: whitelisting /opt directory --- src/firejail/firejail.h | 4 +++- src/firejail/fs_whitelist.c | 41 ++++++++++++++++++++++++++++++++++++++++- src/man/firejail.txt | 2 +- 3 files changed, 44 insertions(+), 3 deletions(-) diff --git a/src/firejail/firejail.h b/src/firejail/firejail.h index 25a39d0c4..9ba3b78ab 100644 --- a/src/firejail/firejail.h +++ b/src/firejail/firejail.h @@ -46,6 +46,7 @@ #define WHITELIST_MEDIA_DIR "/run/firejail/mnt/orig-media" #define WHITELIST_VAR_DIR "/run/firejail/mnt/orig-var" #define WHITELIST_DEV_DIR "/run/firejail/mnt/orig-dev" +#define WHITELIST_OPT_DIR "/run/firejail/mnt/orig-opt" #define XAUTHORITY_FILE "/run/firejail/mnt/.Xauthority" #define HOSTNAME_FILE "/run/firejail/mnt/hostname" @@ -103,7 +104,8 @@ typedef struct profile_entry_t { unsigned tmp_dir:1; // whitelist in /tmp directory unsigned media_dir:1; // whitelist in /media directory unsigned var_dir:1; // whitelist in /var directory - unsigned dev_dir:1; // whitelist in /tmp directory + unsigned dev_dir:1; // whitelist in /dev directory + unsigned opt_dir:1; // whitelist in /opt directory }ProfileEntry; typedef struct config_t { diff --git a/src/firejail/fs_whitelist.c b/src/firejail/fs_whitelist.c index 8b5444ebc..9016e3923 100644 --- a/src/firejail/fs_whitelist.c +++ b/src/firejail/fs_whitelist.c @@ -126,6 +126,16 @@ static void whitelist_path(ProfileEntry *entry) { if (asprintf(&wfile, "%s/%s", WHITELIST_DEV_DIR, fname) == -1) errExit("asprintf"); } + else if (entry->opt_dir) { + fname = path + 4; // strlen("/opt") + if (*fname == '\0') { + fprintf(stderr, "Error: file %s is not in /opt directory, exiting...\n", path); + exit(1); + } + + if (asprintf(&wfile, "%s/%s", WHITELIST_OPT_DIR, fname) == -1) + errExit("asprintf"); + } // check if the file exists struct stat s; @@ -191,6 +201,7 @@ void fs_whitelist(void) { int media_dir = 0; // /media directory flag int var_dir = 0; // /var directory flag int dev_dir = 0; // /dev directory flag + int opt_dir = 0; // /opt directory flag // verify whitelist files, extract symbolic links, etc. while (entry) { @@ -269,6 +280,13 @@ void fs_whitelist(void) { if (strncmp(fname, "/dev/", 5) != 0) goto errexit; } + else if (strncmp(new_name, "/opt/", 5) == 0) { + entry->opt_dir = 1; + opt_dir = 1; + // both path and absolute path are under /dev + if (strncmp(fname, "/opt/", 5) != 0) + goto errexit; + } else goto errexit; @@ -390,13 +408,34 @@ void fs_whitelist(void) { if (mount("/dev", WHITELIST_DEV_DIR, NULL, MS_BIND|MS_REC, NULL) < 0) errExit("mount bind"); - // mount tmpfs on /var + // mount tmpfs on /dev if (arg_debug) printf("Mounting tmpfs on /dev directory\n"); if (mount("tmpfs", "/dev", "tmpfs", MS_NOSUID | MS_STRICTATIME | MS_REC, "mode=755,gid=0") < 0) errExit("mounting tmpfs on /dev"); } + // /opt mountpoint + if (opt_dir) { + // keep a copy of real /opt directory in WHITELIST_DEV_DIR + int rv = mkdir(WHITELIST_OPT_DIR, S_IRWXU | S_IRWXG | S_IRWXO); + if (rv == -1) + errExit("mkdir"); + if (chown(WHITELIST_OPT_DIR, 0, 0) < 0) + errExit("chown"); + if (chmod(WHITELIST_OPT_DIR, 0755) < 0) + errExit("chmod"); + + if (mount("/opt", WHITELIST_OPT_DIR, NULL, MS_BIND|MS_REC, NULL) < 0) + errExit("mount bind"); + + // mount tmpfs on /opt + if (arg_debug) + printf("Mounting tmpfs on /opt directory\n"); + if (mount("tmpfs", "/opt", "tmpfs", MS_NOSUID | MS_STRICTATIME | MS_REC, "mode=755,gid=0") < 0) + errExit("mounting tmpfs on /opt"); + } + // go through profile rules again, and interpret whitelist commands entry = cfg.profile; while (entry) { diff --git a/src/man/firejail.txt b/src/man/firejail.txt index d144fac10..39e0dbaf7 100644 --- a/src/man/firejail.txt +++ b/src/man/firejail.txt @@ -1291,7 +1291,7 @@ $ firejail \-\-version firejail version 0.9.27 .TP \fB\-\-whitelist=dirname_or_filename -Whitelist directory or file. This feature is implemented only for user home, /dev, /media, /var, and /tmp directories. +Whitelist directory or file. This feature is implemented only for user home, /dev, /media, /opt, /var, and /tmp directories. .br .br -- cgit v1.2.3-54-g00ecf