diff options
author | netblue30 <netblue30@yahoo.com> | 2016-04-20 12:43:25 -0400 |
---|---|---|
committer | netblue30 <netblue30@yahoo.com> | 2016-04-20 12:43:25 -0400 |
commit | 4699843c98b6338486cb3e32cd6256708553b614 (patch) | |
tree | 8a6754f20e1609b740e1bec2f3e360726b722ec4 | |
parent | fix mkdir description in man firejail-profile (diff) | |
download | firejail-4699843c98b6338486cb3e32cd6256708553b614.tar.gz firejail-4699843c98b6338486cb3e32cd6256708553b614.tar.zst firejail-4699843c98b6338486cb3e32cd6256708553b614.zip |
added --read-write option
-rw-r--r-- | src/firejail/firejail.h | 5 | ||||
-rw-r--r-- | src/firejail/fs.c | 5 | ||||
-rw-r--r-- | src/firejail/fs_rdwr.c | 93 | ||||
-rw-r--r-- | src/firejail/main.c | 8 | ||||
-rw-r--r-- | src/firejail/profile.c | 12 |
5 files changed, 121 insertions, 2 deletions
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); | |||
568 | #define CFG_MAX 8 // this should always be the last entry | 568 | #define CFG_MAX 8 // this should always be the last entry |
569 | int checkcfg(int val); | 569 | int checkcfg(int val); |
570 | 570 | ||
571 | // fs_rdwr.c | ||
572 | void fs_rdwr_add(const char *path); | ||
573 | void fs_rdwr(void); | ||
574 | |||
575 | |||
571 | #endif | 576 | #endif |
572 | 577 | ||
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) { | |||
729 | printf("Mounting read-only /bin, /sbin, /lib, /lib32, /lib64, /usr"); | 729 | printf("Mounting read-only /bin, /sbin, /lib, /lib32, /lib64, /usr"); |
730 | if (!arg_writable_etc) { | 730 | if (!arg_writable_etc) { |
731 | fs_rdonly("/etc"); | 731 | fs_rdonly("/etc"); |
732 | if (arg_debug) printf(", /etc"); | ||
733 | } | 732 | } |
734 | if (!arg_writable_var) { | 733 | if (!arg_writable_var) { |
735 | fs_rdonly("/var"); | 734 | fs_rdonly("/var"); |
736 | if (arg_debug) printf(", /var"); | ||
737 | } | 735 | } |
738 | if (arg_debug) printf("\n"); | 736 | if (arg_debug) printf("\n"); |
739 | fs_rdonly("/bin"); | 737 | fs_rdonly("/bin"); |
@@ -764,6 +762,9 @@ void fs_basic_fs(void) { | |||
764 | disable_firejail_config(); | 762 | disable_firejail_config(); |
765 | else | 763 | else |
766 | fprintf(stderr, "Warning: masking /etc/firejail disabled when starting the sandbox as root\n"); | 764 | fprintf(stderr, "Warning: masking /etc/firejail disabled when starting the sandbox as root\n"); |
765 | |||
766 | if (getuid() == 0) | ||
767 | fs_rdwr(); | ||
767 | } | 768 | } |
768 | 769 | ||
769 | 770 | ||
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 @@ | |||
1 | /* | ||
2 | * Copyright (C) 2014-2016 Firejail Authors | ||
3 | * | ||
4 | * This file is part of firejail project | ||
5 | * | ||
6 | * This program is free software; you can redistribute it and/or modify | ||
7 | * it under the terms of the GNU General Public License as published by | ||
8 | * the Free Software Foundation; either version 2 of the License, or | ||
9 | * (at your option) any later version. | ||
10 | * | ||
11 | * This program is distributed in the hope that it will be useful, | ||
12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
14 | * GNU General Public License for more details. | ||
15 | * | ||
16 | * You should have received a copy of the GNU General Public License along | ||
17 | * with this program; if not, write to the Free Software Foundation, Inc., | ||
18 | * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. | ||
19 | */ | ||
20 | #include "firejail.h" | ||
21 | #include <sys/mount.h> | ||
22 | #include <sys/stat.h> | ||
23 | #include <sys/types.h> | ||
24 | #include <sys/wait.h> | ||
25 | #include <unistd.h> | ||
26 | |||
27 | typedef struct rdwr_t { | ||
28 | struct rdwr_t *next; | ||
29 | const char *path; | ||
30 | } RDWR; | ||
31 | |||
32 | RDWR *rdwr = NULL; | ||
33 | |||
34 | void fs_rdwr_add(const char *path) { | ||
35 | // verify path | ||
36 | if (*path != '/') { | ||
37 | fprintf(stderr, "Error: invalid path for read-write command\n"); | ||
38 | exit(1); | ||
39 | } | ||
40 | invalid_filename(path); | ||
41 | if (is_link(path)) { | ||
42 | fprintf(stderr, "Error: invalid symbolic link for read-write command\n"); | ||
43 | exit(1); | ||
44 | } | ||
45 | if (strstr(path, "..")) { | ||
46 | fprintf(stderr, "Error: invalid path for read-write command\n"); | ||
47 | exit(1); | ||
48 | } | ||
49 | |||
50 | // print warning if the file doesn't exist | ||
51 | struct stat s; | ||
52 | if (stat(path, &s) == -1) { | ||
53 | fprintf(stderr, "Warning: %s not found, skipping read-write command\n", path); | ||
54 | return; | ||
55 | } | ||
56 | |||
57 | // build list entry | ||
58 | RDWR *r = malloc(sizeof(RDWR)); | ||
59 | if (!r) | ||
60 | errExit("malloc"); | ||
61 | memset(r, 0, sizeof(RDWR)); | ||
62 | r->path = path; | ||
63 | |||
64 | // add | ||
65 | r->next = rdwr; | ||
66 | rdwr = r; | ||
67 | } | ||
68 | |||
69 | static void mount_rdwr(const char *path) { | ||
70 | assert(path); | ||
71 | // check directory exists | ||
72 | struct stat s; | ||
73 | int rv = stat(path, &s); | ||
74 | if (rv == 0) { | ||
75 | // mount --bind /bin /bin | ||
76 | if (mount(path, path, NULL, MS_BIND|MS_REC, NULL) < 0) | ||
77 | errExit("mount read-write"); | ||
78 | // mount --bind -o remount,rw /bin | ||
79 | if (mount(NULL, path, NULL, MS_BIND|MS_REMOUNT|MS_REC, NULL) < 0) | ||
80 | errExit("mount read-write"); | ||
81 | fs_logger2("read-write", path); | ||
82 | } | ||
83 | } | ||
84 | |||
85 | void fs_rdwr(void) { | ||
86 | RDWR *ptr = rdwr; | ||
87 | |||
88 | while (ptr) { | ||
89 | mount_rdwr(ptr->path); | ||
90 | ptr = ptr->next; | ||
91 | } | ||
92 | } | ||
93 | |||
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) { | |||
1097 | profile_check_line(line, 0, NULL); // will exit if something wrong | 1097 | profile_check_line(line, 0, NULL); // will exit if something wrong |
1098 | profile_add(line); | 1098 | profile_add(line); |
1099 | } | 1099 | } |
1100 | else if (strncmp(argv[i], "--read-write=", 13) == 0) { | ||
1101 | char *line; | ||
1102 | if (asprintf(&line, "read-write %s", argv[i] + 13) == -1) | ||
1103 | errExit("asprintf"); | ||
1104 | |||
1105 | profile_check_line(line, 0, NULL); // will exit if something wrong | ||
1106 | // profile_add(line); is not necessary | ||
1107 | } | ||
1100 | else if (strcmp(argv[i], "--overlay") == 0) { | 1108 | else if (strcmp(argv[i], "--overlay") == 0) { |
1101 | if (cfg.chrootdir) { | 1109 | if (cfg.chrootdir) { |
1102 | fprintf(stderr, "Error: --overlay and --chroot options are mutually exclusive\n"); | 1110 | 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) { | |||
716 | return 0; | 716 | return 0; |
717 | } | 717 | } |
718 | 718 | ||
719 | // read-write | ||
720 | if (strncmp(ptr, "read-write ", 11) == 0) { | ||
721 | if (getuid() != 0) { | ||
722 | fprintf(stderr, "Error: read-write command is available only for root user\n"); | ||
723 | exit(1); | ||
724 | } | ||
725 | printf("here %d\n", __LINE__); | ||
726 | fs_rdwr_add(ptr + 11); | ||
727 | printf("here %d\n", __LINE__); | ||
728 | return 0; | ||
729 | } | ||
730 | |||
719 | // rest of filesystem | 731 | // rest of filesystem |
720 | if (strncmp(ptr, "blacklist ", 10) == 0) | 732 | if (strncmp(ptr, "blacklist ", 10) == 0) |
721 | ptr += 10; | 733 | ptr += 10; |