From 4699843c98b6338486cb3e32cd6256708553b614 Mon Sep 17 00:00:00 2001 From: netblue30 Date: Wed, 20 Apr 2016 12:43:25 -0400 Subject: added --read-write option --- src/firejail/firejail.h | 5 +++ src/firejail/fs.c | 5 +-- src/firejail/fs_rdwr.c | 93 +++++++++++++++++++++++++++++++++++++++++++++++++ src/firejail/main.c | 8 +++++ src/firejail/profile.c | 12 +++++++ 5 files changed, 121 insertions(+), 2 deletions(-) create mode 100644 src/firejail/fs_rdwr.c (limited to 'src') diff --git a/src/firejail/firejail.h b/src/firejail/firejail.h index ece1eee4e..302883310 100644 --- a/src/firejail/firejail.h +++ b/src/firejail/firejail.h @@ -568,5 +568,10 @@ void sandboxfs(int op, pid_t pid, const char *patqh); #define CFG_MAX 8 // this should always be the last entry int checkcfg(int val); +// fs_rdwr.c +void fs_rdwr_add(const char *path); +void fs_rdwr(void); + + #endif diff --git a/src/firejail/fs.c b/src/firejail/fs.c index 4c2510021..171b4848c 100644 --- a/src/firejail/fs.c +++ b/src/firejail/fs.c @@ -729,11 +729,9 @@ void fs_basic_fs(void) { printf("Mounting read-only /bin, /sbin, /lib, /lib32, /lib64, /usr"); if (!arg_writable_etc) { fs_rdonly("/etc"); - if (arg_debug) printf(", /etc"); } if (!arg_writable_var) { fs_rdonly("/var"); - if (arg_debug) printf(", /var"); } if (arg_debug) printf("\n"); fs_rdonly("/bin"); @@ -764,6 +762,9 @@ void fs_basic_fs(void) { disable_firejail_config(); else fprintf(stderr, "Warning: masking /etc/firejail disabled when starting the sandbox as root\n"); + + if (getuid() == 0) + fs_rdwr(); } diff --git a/src/firejail/fs_rdwr.c b/src/firejail/fs_rdwr.c new file mode 100644 index 000000000..68df6465f --- /dev/null +++ b/src/firejail/fs_rdwr.c @@ -0,0 +1,93 @@ +/* + * Copyright (C) 2014-2016 Firejail Authors + * + * This file is part of firejail project + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ +#include "firejail.h" +#include +#include +#include +#include +#include + +typedef struct rdwr_t { + struct rdwr_t *next; + const char *path; +} RDWR; + +RDWR *rdwr = NULL; + +void fs_rdwr_add(const char *path) { + // verify path + if (*path != '/') { + fprintf(stderr, "Error: invalid path for read-write command\n"); + exit(1); + } + invalid_filename(path); + if (is_link(path)) { + fprintf(stderr, "Error: invalid symbolic link for read-write command\n"); + exit(1); + } + if (strstr(path, "..")) { + fprintf(stderr, "Error: invalid path for read-write command\n"); + exit(1); + } + + // print warning if the file doesn't exist + struct stat s; + if (stat(path, &s) == -1) { + fprintf(stderr, "Warning: %s not found, skipping read-write command\n", path); + return; + } + + // build list entry + RDWR *r = malloc(sizeof(RDWR)); + if (!r) + errExit("malloc"); + memset(r, 0, sizeof(RDWR)); + r->path = path; + + // add + r->next = rdwr; + rdwr = r; +} + +static void mount_rdwr(const char *path) { + assert(path); + // check directory exists + struct stat s; + int rv = stat(path, &s); + if (rv == 0) { + // mount --bind /bin /bin + if (mount(path, path, NULL, MS_BIND|MS_REC, NULL) < 0) + errExit("mount read-write"); + // mount --bind -o remount,rw /bin + if (mount(NULL, path, NULL, MS_BIND|MS_REMOUNT|MS_REC, NULL) < 0) + errExit("mount read-write"); + fs_logger2("read-write", path); + } +} + +void fs_rdwr(void) { + RDWR *ptr = rdwr; + + while (ptr) { + mount_rdwr(ptr->path); + ptr = ptr->next; + } +} + diff --git a/src/firejail/main.c b/src/firejail/main.c index 0f7809fea..54b9c05f0 100644 --- a/src/firejail/main.c +++ b/src/firejail/main.c @@ -1097,6 +1097,14 @@ int main(int argc, char **argv) { profile_check_line(line, 0, NULL); // will exit if something wrong profile_add(line); } + else if (strncmp(argv[i], "--read-write=", 13) == 0) { + char *line; + if (asprintf(&line, "read-write %s", argv[i] + 13) == -1) + errExit("asprintf"); + + profile_check_line(line, 0, NULL); // will exit if something wrong + // profile_add(line); is not necessary + } else if (strcmp(argv[i], "--overlay") == 0) { if (cfg.chrootdir) { fprintf(stderr, "Error: --overlay and --chroot options are mutually exclusive\n"); diff --git a/src/firejail/profile.c b/src/firejail/profile.c index 9e0f0325e..38052c4f1 100644 --- a/src/firejail/profile.c +++ b/src/firejail/profile.c @@ -716,6 +716,18 @@ int profile_check_line(char *ptr, int lineno, const char *fname) { return 0; } + // read-write + if (strncmp(ptr, "read-write ", 11) == 0) { + if (getuid() != 0) { + fprintf(stderr, "Error: read-write command is available only for root user\n"); + exit(1); + } +printf("here %d\n", __LINE__); + fs_rdwr_add(ptr + 11); +printf("here %d\n", __LINE__); + return 0; + } + // rest of filesystem if (strncmp(ptr, "blacklist ", 10) == 0) ptr += 10; -- cgit v1.2.3-54-g00ecf