From 45429215529c9d683322a4d272d1f33a67446fdd Mon Sep 17 00:00:00 2001 From: valoq Date: Sat, 15 Oct 2016 22:56:45 +0200 Subject: added /srv in whitelist option --- src/firejail/firejail.h | 2 ++ src/firejail/fs_whitelist.c | 61 ++++++++++++++++++++++++++++++++++++++++++-- src/man/firejail-profile.txt | 2 +- src/man/firejail.txt | 2 +- 4 files changed, 63 insertions(+), 4 deletions(-) diff --git a/src/firejail/firejail.h b/src/firejail/firejail.h index 5f736f700..dafa5919c 100644 --- a/src/firejail/firejail.h +++ b/src/firejail/firejail.h @@ -60,6 +60,7 @@ #define RUN_WHITELIST_VAR_DIR "/run/firejail/mnt/orig-var" #define RUN_WHITELIST_DEV_DIR "/run/firejail/mnt/orig-dev" #define RUN_WHITELIST_OPT_DIR "/run/firejail/mnt/orig-opt" +#define RUN_WHITELIST_SRV_DIR "/run/firejail/mnt/orig-srv" #define RUN_XAUTHORITY_FILE "/run/firejail/mnt/.Xauthority" #define RUN_XAUTHORITY_SEC_FILE "/run/firejail/mnt/sec.Xauthority" @@ -173,6 +174,7 @@ typedef struct profile_entry_t { unsigned var_dir:1; // whitelist in /var directory unsigned dev_dir:1; // whitelist in /dev directory unsigned opt_dir:1; // whitelist in /opt directory + unsigned srv_dir:1; // whitelist in /srv directory }ProfileEntry; typedef struct config_t { diff --git a/src/firejail/fs_whitelist.c b/src/firejail/fs_whitelist.c index 849861805..b1c2774e2 100644 --- a/src/firejail/fs_whitelist.c +++ b/src/firejail/fs_whitelist.c @@ -254,7 +254,16 @@ static void whitelist_path(ProfileEntry *entry) { if (asprintf(&wfile, "%s/%s", RUN_WHITELIST_OPT_DIR, fname) == -1) errExit("asprintf"); } + else if (entry->srv_dir) { + fname = path + 4; // strlen("/srv") + if (*fname == '\0') { + fprintf(stderr, "Error: file %s is not in /srv directory, exiting...\n", path); + exit(1); + } + if (asprintf(&wfile, "%s/%s", RUN_WHITELIST_SRV_DIR, fname) == -1) + errExit("asprintf"); + } // check if the file exists struct stat s; if (wfile && stat(wfile, &s) == 0) { @@ -317,7 +326,7 @@ void fs_whitelist(void) { int var_dir = 0; // /var directory flag int dev_dir = 0; // /dev directory flag int opt_dir = 0; // /opt directory flag - + int srv_dir = 0; // /srv directory flag // verify whitelist files, extract symbolic links, etc. while (entry) { // handle only whitelist commands @@ -387,7 +396,9 @@ void fs_whitelist(void) { dev_dir = 1; else if (strncmp(new_name, "/opt/", 5) == 0) opt_dir = 1; - + else if (strncmp(new_name, "/srv/", 5) == 0) + opt_dir = 1; + continue; } @@ -481,6 +492,16 @@ void fs_whitelist(void) { goto errexit; } } + else if (strncmp(new_name, "/srv/", 5) == 0) { + entry->srv_dir = 1; + srv_dir = 1; + // both path and absolute path are under /srv + if (strncmp(fname, "/srv/", 5) != 0) { + if (arg_debug) + fprintf(stderr, "Debug %d: fname #%s#\n", __LINE__, fname); + goto errexit; + } + } else { if (arg_debug) fprintf(stderr, "Debug %d: \n", __LINE__); @@ -675,6 +696,36 @@ void fs_whitelist(void) { fs_logger("tmpfs /opt"); } + // /srv mountpoint + if (srv_dir) { + // check if /srv directory exists + struct stat s; + if (stat("/srv", &s) == 0) { + // keep a copy of real /srv directory in RUN_WHITELIST_SRV_DIR + int rv = mkdir(RUN_WHITELIST_SRV_DIR, 0755); + if (rv == -1) + errExit("mkdir"); + if (chown(RUN_WHITELIST_SRV_DIR, 0, 0) < 0) + errExit("chown"); + if (chmod(RUN_WHITELIST_SRV_DIR, 0755) < 0) + errExit("chmod"); + + if (mount("/srv", RUN_WHITELIST_SRV_DIR, NULL, MS_BIND|MS_REC, NULL) < 0) + errExit("mount bind"); + + // mount tmpfs on /srv + if (arg_debug || arg_debug_whitelists) + printf("Mounting tmpfs on /srv directory\n"); + if (mount("tmpfs", "/srv", "tmpfs", MS_NOSUID | MS_STRICTATIME | MS_REC, "mode=755,gid=0") < 0) + errExit("mounting tmpfs on /srv"); + fs_logger("tmpfs /srv"); + } + else + srv_dir = 0; + } + + + // go through profile rules again, and interpret whitelist commands entry = cfg.profile; while (entry) { @@ -766,6 +817,12 @@ void fs_whitelist(void) { fs_logger2("tmpfs", RUN_WHITELIST_MNT_DIR); } + // mask the real /srv directory, currently mounted on RUN_WHITELIST_SRV_DIR + if (srv_dir) { + if (mount("tmpfs", RUN_WHITELIST_SRV_DIR, "tmpfs", MS_NOSUID | MS_STRICTATIME | MS_REC, "mode=755,gid=0") < 0) + errExit("mount tmpfs"); + fs_logger2("tmpfs", RUN_WHITELIST_SRV_DIR); + if (new_name) free(new_name); diff --git a/src/man/firejail-profile.txt b/src/man/firejail-profile.txt index d420fab7a..09dc46bbc 100644 --- a/src/man/firejail-profile.txt +++ b/src/man/firejail-profile.txt @@ -218,7 +218,7 @@ Blacklist violations logged to syslog. Whitelist directory or file. A temporary file system is mounted on the top directory, and the whitelisted files are mount-binded inside. Modifications to whitelisted files are persistent, everything else is discarded when the sandbox is closed. The top directory could be -user home, /dev, /media, /mnt, /opt, /var, and /tmp. +user home, /dev, /media, /mnt, /opt, /srv, /var, and /tmp. .br .br diff --git a/src/man/firejail.txt b/src/man/firejail.txt index 4aebb71e8..666a6a8ef 100644 --- a/src/man/firejail.txt +++ b/src/man/firejail.txt @@ -1622,7 +1622,7 @@ $ firejail \-\-net=br0 --veth-name=if0 Whitelist directory or file. A temporary file system is mounted on the top directory, and the whitelisted files are mount-binded inside. Modifications to whitelisted files are persistent, everything else is discarded when the sandbox is closed. The top directory could be -user home, /dev, /media, /mnt, /opt, /var, and /tmp. +user home, /dev, /media, /mnt, /opt, /srv, /var, and /tmp. .br .br -- cgit v1.2.3-54-g00ecf