From afe9fe993293a27dc345f6bca2a4b7ea964120b8 Mon Sep 17 00:00:00 2001 From: netblue30 Date: Tue, 19 Jul 2016 13:03:24 -0400 Subject: --read-write rework --- RELNOTES | 1 + src/bash_completion/firejail.bash_completion | 4 +++ src/firejail/firejail.h | 4 --- src/firejail/fs.c | 39 +++++++++++++++++++++++++--- src/firejail/fs_rdwr.c | 3 +++ src/firejail/main.c | 2 +- src/firejail/profile.c | 12 ++------- src/man/firejail.txt | 17 ++++++++---- todo | 2 +- 9 files changed, 60 insertions(+), 24 deletions(-) diff --git a/RELNOTES b/RELNOTES index 3ff1bf1ad..067bac4ea 100644 --- a/RELNOTES +++ b/RELNOTES @@ -1,6 +1,7 @@ firejail (0.9.41) baseline; urgency=low * work in progress... * deprecated --user option, please use "sudo -u username firejail" instead + * --read-write opton rework * AppImage support (--appimage) * Sandbox auditing support (--audit) * remove environment variable (--rmenv) diff --git a/src/bash_completion/firejail.bash_completion b/src/bash_completion/firejail.bash_completion index 78bd622fc..d3dcd57d0 100644 --- a/src/bash_completion/firejail.bash_completion +++ b/src/bash_completion/firejail.bash_completion @@ -47,6 +47,10 @@ _firejail() _filedir return 0 ;; + --read-write) + _filedir + return 0 + ;; --bind) _filedir return 0 diff --git a/src/firejail/firejail.h b/src/firejail/firejail.h index 8856986e6..29bb6c494 100644 --- a/src/firejail/firejail.h +++ b/src/firejail/firejail.h @@ -584,10 +584,6 @@ extern char *xephyr_screen; extern char *xephyr_extra_params; int checkcfg(int val); -// fs_rdwr.c -void fs_rdwr_add(const char *path); -void fs_rdwr(void); - // appimage.c void appimage_set(const char *appimage_path); void appimage_clear(void); diff --git a/src/firejail/fs.c b/src/firejail/fs.c index d426636d8..630458549 100644 --- a/src/firejail/fs.c +++ b/src/firejail/fs.c @@ -27,6 +27,8 @@ #include #include +static void fs_rdwr(const char *dir); + static void create_empty_dir(void) { struct stat s; @@ -229,6 +231,7 @@ typedef enum { MOUNT_READONLY, MOUNT_TMPFS, MOUNT_NOEXEC, + MOUNT_RDWR, OPERATION_MAX } OPERATION; @@ -329,6 +332,12 @@ static void disable_file(OPERATION op, const char *filename) { if (arg_debug) printf("Mounting read-only %s\n", fname); fs_rdonly(fname); +// todo: last_disable = SUCCESSFUL; + } + else if (op == MOUNT_RDWR) { + if (arg_debug) + printf("Mounting read-only %s\n", fname); + fs_rdwr(fname); // todo: last_disable = SUCCESSFUL; } else if (op == MOUNT_NOEXEC) { @@ -492,6 +501,10 @@ void fs_blacklist(void) { ptr = entry->data + 10; op = MOUNT_READONLY; } + else if (strncmp(entry->data, "read-write ", 11) == 0) { + ptr = entry->data + 11; + op = MOUNT_RDWR; + } else if (strncmp(entry->data, "noexec ", 7) == 0) { ptr = entry->data + 7; op = MOUNT_NOEXEC; @@ -560,6 +573,29 @@ void fs_rdonly(const char *dir) { } } +static void fs_rdwr(const char *dir) { + assert(dir); + // check directory exists + struct stat s; + int rv = stat(dir, &s); + if (rv == 0) { + // if the file is outside /home directory, allow only root user + uid_t u = getuid(); + if (u != 0 && s.st_uid != u) { + fprintf(stderr, "Warning: you are not allowed to change %s to read-write\n", dir); + return; + } + + // mount --bind /bin /bin + if (mount(dir, dir, NULL, MS_BIND|MS_REC, NULL) < 0) + errExit("mount read-write"); + // mount --bind -o remount,rw /bin + if (mount(NULL, dir, NULL, MS_BIND|MS_REMOUNT|MS_REC, NULL) < 0) + errExit("mount read-write"); + fs_logger2("read-write", dir); + } +} + void fs_noexec(const char *dir) { assert(dir); // check directory exists @@ -757,9 +793,6 @@ void fs_basic_fs(void) { // firejail sandboxes (firejail --force) if (getuid() != 0) disable_firejail_config(); - - if (getuid() == 0) - fs_rdwr(); } diff --git a/src/firejail/fs_rdwr.c b/src/firejail/fs_rdwr.c index 68df6465f..e098be416 100644 --- a/src/firejail/fs_rdwr.c +++ b/src/firejail/fs_rdwr.c @@ -17,6 +17,7 @@ * with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ +#if 0 #include "firejail.h" #include #include @@ -91,3 +92,5 @@ void fs_rdwr(void) { } } +#endif + diff --git a/src/firejail/main.c b/src/firejail/main.c index 703b9913b..25063700c 100644 --- a/src/firejail/main.c +++ b/src/firejail/main.c @@ -1206,7 +1206,7 @@ int main(int argc, char **argv) { errExit("asprintf"); profile_check_line(line, 0, NULL); // will exit if something wrong - // profile_add(line); is not necessary + profile_add(line); } else if (strcmp(argv[i], "--overlay") == 0) { if (cfg.chrootdir) { diff --git a/src/firejail/profile.c b/src/firejail/profile.c index 40e2e4330..46ef0921d 100644 --- a/src/firejail/profile.c +++ b/src/firejail/profile.c @@ -716,16 +716,6 @@ 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); - } - fs_rdwr_add(ptr + 11); - return 0; - } - // rest of filesystem if (strncmp(ptr, "blacklist ", 10) == 0) ptr += 10; @@ -747,6 +737,8 @@ int profile_check_line(char *ptr, int lineno, const char *fname) { } else if (strncmp(ptr, "read-only ", 10) == 0) ptr += 10; + else if (strncmp(ptr, "read-write ", 11) == 0) + ptr += 11; else if (strncmp(ptr, "noexec ", 7) == 0) ptr += 7; else if (strncmp(ptr, "tmpfs ", 6) == 0) { diff --git a/src/man/firejail.txt b/src/man/firejail.txt index f7079200e..fed573e6c 100644 --- a/src/man/firejail.txt +++ b/src/man/firejail.txt @@ -1183,17 +1183,24 @@ $ firejail \-\-read-only=~/.mozilla firefox A short note about mixing \-\-whitelist and \-\-read-only options. Whitelisted directories should be made read-only independently. Making a parent directory read-only, will not make the whitelist read-only. Example: +.br + .br $ firejail --whitelist=~/work --read-only=~ --read-only=~/work .TP \fB\-\-read-write=dirname_or_filename -By default, the sandbox mounts system directories read-only. -These directories are /etc, /var, /usr, /bin, /sbin, /lib, /lib32, /libx32 and /lib64. -Use this option to mount read-write files or directories inside the system directories. +Set directory or file read-write. Only files or directories belonging to the current user are allowed for +this operation. Example: +.br + +.br +$ mkdir ~/test +.br +$ touch ~/test/a +.br +$ firejail --read-only=~/test --read-write=~/test/a -This option is available only to root user. It has no effect when --chroot or --overlay are also set. In these -cases the system directories are mounted read-write. .TP \fB\-\-rlimit-fsize=number diff --git a/todo b/todo index 491f9d8eb..30e8f3949 100644 --- a/todo +++ b/todo @@ -245,4 +245,4 @@ References https://bestpractices.coreinfrastructure.org https://twit.tv/shows/floss-weekly/episodes/389 -@netblue30 \ No newline at end of file +22. add support for read-write and noexec to Firetools -- cgit v1.2.3-70-g09d2