diff options
author | netblue30 <netblue30@yahoo.com> | 2015-11-15 09:51:41 -0500 |
---|---|---|
committer | netblue30 <netblue30@yahoo.com> | 2015-11-15 09:51:41 -0500 |
commit | 8f2a6e5df652d23f4a210623e4a18689951c6a8c (patch) | |
tree | 80003461408d64798a94ccc0f3596fcb6484a89a /src | |
parent | added netlink to the protocol list for firefox, required by some camera devic... (diff) | |
download | firejail-8f2a6e5df652d23f4a210623e4a18689951c6a8c.tar.gz firejail-8f2a6e5df652d23f4a210623e4a18689951c6a8c.tar.zst firejail-8f2a6e5df652d23f4a210623e4a18689951c6a8c.zip |
whitelist enhancements
Diffstat (limited to 'src')
-rw-r--r-- | src/firejail/firejail.h | 8 | ||||
-rw-r--r-- | src/firejail/fs_whitelist.c | 121 | ||||
-rw-r--r-- | src/man/firejail.txt | 4 |
3 files changed, 130 insertions, 3 deletions
diff --git a/src/firejail/firejail.h b/src/firejail/firejail.h index 23ed11626..4f8968e4a 100644 --- a/src/firejail/firejail.h +++ b/src/firejail/firejail.h | |||
@@ -39,8 +39,13 @@ | |||
39 | #define DRI_DIR "/run/firejail/mnt/dri" | 39 | #define DRI_DIR "/run/firejail/mnt/dri" |
40 | #define PULSE_DIR "/run/firejail/mnt/pulse" | 40 | #define PULSE_DIR "/run/firejail/mnt/pulse" |
41 | #define DEVLOG_FILE "/run/firejail/mnt/devlog" | 41 | #define DEVLOG_FILE "/run/firejail/mnt/devlog" |
42 | |||
42 | #define WHITELIST_HOME_DIR "/run/firejail/mnt/orig-home" | 43 | #define WHITELIST_HOME_DIR "/run/firejail/mnt/orig-home" |
43 | #define WHITELIST_TMP_DIR "/run/firejail/mnt/orig-tmp" | 44 | #define WHITELIST_TMP_DIR "/run/firejail/mnt/orig-tmp" |
45 | #define WHITELIST_MEDIA_DIR "/run/firejail/mnt/orig-media" | ||
46 | #define WHITELIST_VAR_DIR "/run/firejail/mnt/orig-var" | ||
47 | #define WHITELIST_DEV_DIR "/run/firejail/mnt/orig-dev" | ||
48 | |||
44 | #define XAUTHORITY_FILE "/run/firejail/mnt/.Xauthority" | 49 | #define XAUTHORITY_FILE "/run/firejail/mnt/.Xauthority" |
45 | #define HOSTNAME_FILE "/run/firejail/mnt/hostname" | 50 | #define HOSTNAME_FILE "/run/firejail/mnt/hostname" |
46 | #define RESOLVCONF_FILE "/run/firejail/mnt/resolv.conf" | 51 | #define RESOLVCONF_FILE "/run/firejail/mnt/resolv.conf" |
@@ -93,6 +98,9 @@ typedef struct profile_entry_t { | |||
93 | char *link; // link name - set if the file is a link | 98 | char *link; // link name - set if the file is a link |
94 | unsigned home_dir:1; // whitelist in /home/user directory | 99 | unsigned home_dir:1; // whitelist in /home/user directory |
95 | unsigned tmp_dir:1; // whitelist in /tmp directory | 100 | unsigned tmp_dir:1; // whitelist in /tmp directory |
101 | unsigned media_dir:1; // whitelist in /media directory | ||
102 | unsigned var_dir:1; // whitelist in /var directory | ||
103 | unsigned dev_dir:1; // whitelist in /tmp directory | ||
96 | }ProfileEntry; | 104 | }ProfileEntry; |
97 | 105 | ||
98 | typedef struct config_t { | 106 | typedef struct config_t { |
diff --git a/src/firejail/fs_whitelist.c b/src/firejail/fs_whitelist.c index 2751a8c71..3514c073d 100644 --- a/src/firejail/fs_whitelist.c +++ b/src/firejail/fs_whitelist.c | |||
@@ -83,6 +83,36 @@ static void whitelist_path(ProfileEntry *entry) { | |||
83 | if (asprintf(&wfile, "%s/%s", WHITELIST_TMP_DIR, fname) == -1) | 83 | if (asprintf(&wfile, "%s/%s", WHITELIST_TMP_DIR, fname) == -1) |
84 | errExit("asprintf"); | 84 | errExit("asprintf"); |
85 | } | 85 | } |
86 | else if (entry->media_dir) { | ||
87 | fname = path + 6; // strlen("/media") | ||
88 | if (*fname == '\0') { | ||
89 | fprintf(stderr, "Error: file %s is not in /media directory, exiting...\n", path); | ||
90 | exit(1); | ||
91 | } | ||
92 | |||
93 | if (asprintf(&wfile, "%s/%s", WHITELIST_MEDIA_DIR, fname) == -1) | ||
94 | errExit("asprintf"); | ||
95 | } | ||
96 | else if (entry->var_dir) { | ||
97 | fname = path + 4; // strlen("/var") | ||
98 | if (*fname == '\0') { | ||
99 | fprintf(stderr, "Error: file %s is not in /var directory, exiting...\n", path); | ||
100 | exit(1); | ||
101 | } | ||
102 | |||
103 | if (asprintf(&wfile, "%s/%s", WHITELIST_VAR_DIR, fname) == -1) | ||
104 | errExit("asprintf"); | ||
105 | } | ||
106 | else if (entry->dev_dir) { | ||
107 | fname = path + 4; // strlen("/dev") | ||
108 | if (*fname == '\0') { | ||
109 | fprintf(stderr, "Error: file %s is not in /dev directory, exiting...\n", path); | ||
110 | exit(1); | ||
111 | } | ||
112 | |||
113 | if (asprintf(&wfile, "%s/%s", WHITELIST_DEV_DIR, fname) == -1) | ||
114 | errExit("asprintf"); | ||
115 | } | ||
86 | 116 | ||
87 | // check if the file exists | 117 | // check if the file exists |
88 | struct stat s; | 118 | struct stat s; |
@@ -145,6 +175,9 @@ void fs_whitelist(void) { | |||
145 | char *new_name = NULL; | 175 | char *new_name = NULL; |
146 | int home_dir = 0; // /home/user directory flag | 176 | int home_dir = 0; // /home/user directory flag |
147 | int tmp_dir = 0; // /tmp directory flag | 177 | int tmp_dir = 0; // /tmp directory flag |
178 | int media_dir = 0; // /media directory flag | ||
179 | int var_dir = 0; // /var directory flag | ||
180 | int dev_dir = 0; // /dev directory flag | ||
148 | 181 | ||
149 | // verify whitelist files, extract symbolic links, etc. | 182 | // verify whitelist files, extract symbolic links, etc. |
150 | while (entry) { | 183 | while (entry) { |
@@ -173,7 +206,7 @@ void fs_whitelist(void) { | |||
173 | if (*new_name != '/') | 206 | if (*new_name != '/') |
174 | goto errexit; | 207 | goto errexit; |
175 | 208 | ||
176 | // check for home directory or tmp directory | 209 | // check for supported directories |
177 | if (strncmp(new_name, cfg.homedir, strlen(cfg.homedir)) == 0) { | 210 | if (strncmp(new_name, cfg.homedir, strlen(cfg.homedir)) == 0) { |
178 | entry->home_dir = 1; | 211 | entry->home_dir = 1; |
179 | home_dir = 1; | 212 | home_dir = 1; |
@@ -188,6 +221,27 @@ void fs_whitelist(void) { | |||
188 | if (strncmp(fname, "/tmp/", 5) != 0) | 221 | if (strncmp(fname, "/tmp/", 5) != 0) |
189 | goto errexit; | 222 | goto errexit; |
190 | } | 223 | } |
224 | else if (strncmp(new_name, "/media/", 7) == 0) { | ||
225 | entry->media_dir = 1; | ||
226 | media_dir = 1; | ||
227 | // both path and absolute path are under /media | ||
228 | if (strncmp(fname, "/media/", 7) != 0) | ||
229 | goto errexit; | ||
230 | } | ||
231 | else if (strncmp(new_name, "/var/", 5) == 0) { | ||
232 | entry->var_dir = 1; | ||
233 | var_dir = 1; | ||
234 | // both path and absolute path are under /var | ||
235 | if (strncmp(fname, "/var/", 5) != 0) | ||
236 | goto errexit; | ||
237 | } | ||
238 | else if (strncmp(new_name, "/dev/", 5) == 0) { | ||
239 | entry->dev_dir = 1; | ||
240 | dev_dir = 1; | ||
241 | // both path and absolute path are under /dev | ||
242 | if (strncmp(fname, "/dev/", 5) != 0) | ||
243 | goto errexit; | ||
244 | } | ||
191 | else | 245 | else |
192 | goto errexit; | 246 | goto errexit; |
193 | 247 | ||
@@ -249,7 +303,70 @@ void fs_whitelist(void) { | |||
249 | if (arg_debug) | 303 | if (arg_debug) |
250 | printf("Mounting tmpfs on /tmp directory\n"); | 304 | printf("Mounting tmpfs on /tmp directory\n"); |
251 | if (mount("tmpfs", "/tmp", "tmpfs", MS_NOSUID | MS_STRICTATIME | MS_REC, "mode=777,gid=0") < 0) | 305 | if (mount("tmpfs", "/tmp", "tmpfs", MS_NOSUID | MS_STRICTATIME | MS_REC, "mode=777,gid=0") < 0) |
252 | errExit("mounting tmpfs on /tmpt"); | 306 | errExit("mounting tmpfs on /tmp"); |
307 | } | ||
308 | |||
309 | // /media mountpoint | ||
310 | if (media_dir) { | ||
311 | // keep a copy of real /media directory in WHITELIST_MEDIA_DIR | ||
312 | int rv = mkdir(WHITELIST_MEDIA_DIR, S_IRWXU | S_IRWXG | S_IRWXO); | ||
313 | if (rv == -1) | ||
314 | errExit("mkdir"); | ||
315 | if (chown(WHITELIST_MEDIA_DIR, 0, 0) < 0) | ||
316 | errExit("chown"); | ||
317 | if (chmod(WHITELIST_MEDIA_DIR, 0755) < 0) | ||
318 | errExit("chmod"); | ||
319 | |||
320 | if (mount("/media", WHITELIST_MEDIA_DIR, NULL, MS_BIND|MS_REC, NULL) < 0) | ||
321 | errExit("mount bind"); | ||
322 | |||
323 | // mount tmpfs on /media | ||
324 | if (arg_debug) | ||
325 | printf("Mounting tmpfs on /media directory\n"); | ||
326 | if (mount("tmpfs", "/media", "tmpfs", MS_NOSUID | MS_STRICTATIME | MS_REC, "mode=755,gid=0") < 0) | ||
327 | errExit("mounting tmpfs on /media"); | ||
328 | } | ||
329 | |||
330 | // /media mountpoint | ||
331 | if (var_dir) { | ||
332 | // keep a copy of real /var directory in WHITELIST_VAR_DIR | ||
333 | int rv = mkdir(WHITELIST_VAR_DIR, S_IRWXU | S_IRWXG | S_IRWXO); | ||
334 | if (rv == -1) | ||
335 | errExit("mkdir"); | ||
336 | if (chown(WHITELIST_VAR_DIR, 0, 0) < 0) | ||
337 | errExit("chown"); | ||
338 | if (chmod(WHITELIST_VAR_DIR, 0755) < 0) | ||
339 | errExit("chmod"); | ||
340 | |||
341 | if (mount("/var", WHITELIST_VAR_DIR, NULL, MS_BIND|MS_REC, NULL) < 0) | ||
342 | errExit("mount bind"); | ||
343 | |||
344 | // mount tmpfs on /var | ||
345 | if (arg_debug) | ||
346 | printf("Mounting tmpfs on /var directory\n"); | ||
347 | if (mount("tmpfs", "/var", "tmpfs", MS_NOSUID | MS_STRICTATIME | MS_REC, "mode=755,gid=0") < 0) | ||
348 | errExit("mounting tmpfs on /var"); | ||
349 | } | ||
350 | |||
351 | // /dev mountpoint | ||
352 | if (dev_dir) { | ||
353 | // keep a copy of real /dev directory in WHITELIST_DEV_DIR | ||
354 | int rv = mkdir(WHITELIST_DEV_DIR, S_IRWXU | S_IRWXG | S_IRWXO); | ||
355 | if (rv == -1) | ||
356 | errExit("mkdir"); | ||
357 | if (chown(WHITELIST_DEV_DIR, 0, 0) < 0) | ||
358 | errExit("chown"); | ||
359 | if (chmod(WHITELIST_DEV_DIR, 0755) < 0) | ||
360 | errExit("chmod"); | ||
361 | |||
362 | if (mount("/dev", WHITELIST_DEV_DIR, NULL, MS_BIND|MS_REC, NULL) < 0) | ||
363 | errExit("mount bind"); | ||
364 | |||
365 | // mount tmpfs on /var | ||
366 | if (arg_debug) | ||
367 | printf("Mounting tmpfs on /dev directory\n"); | ||
368 | if (mount("tmpfs", "/dev", "tmpfs", MS_NOSUID | MS_STRICTATIME | MS_REC, "mode=755,gid=0") < 0) | ||
369 | errExit("mounting tmpfs on /dev"); | ||
253 | } | 370 | } |
254 | 371 | ||
255 | // go through profile rules again, and interpret whitelist commands | 372 | // go through profile rules again, and interpret whitelist commands |
diff --git a/src/man/firejail.txt b/src/man/firejail.txt index 46129fdb2..dc518b666 100644 --- a/src/man/firejail.txt +++ b/src/man/firejail.txt | |||
@@ -1241,7 +1241,7 @@ $ firejail \-\-version | |||
1241 | firejail version 0.9.27 | 1241 | firejail version 0.9.27 |
1242 | .TP | 1242 | .TP |
1243 | \fB\-\-whitelist=dirname_or_filename | 1243 | \fB\-\-whitelist=dirname_or_filename |
1244 | Whitelist directory or file. Only files in user home directory are accepted. | 1244 | Whitelist directory or file. This feature is implemented only for user home, /dev, /media, /var, and /tmp directories. |
1245 | .br | 1245 | .br |
1246 | 1246 | ||
1247 | .br | 1247 | .br |
@@ -1249,6 +1249,8 @@ Example: | |||
1249 | .br | 1249 | .br |
1250 | $ firejail \-\-whitelist=~/.mozilla \-\-whitelist=~/Downloads | 1250 | $ firejail \-\-whitelist=~/.mozilla \-\-whitelist=~/Downloads |
1251 | .br | 1251 | .br |
1252 | $ firejail \-\-whitelist=/tmp/.X11-unix --whitelist=/dev/null | ||
1253 | .br | ||
1252 | $ firejail "\-\-whitelist=/home/username/My Virtual Machines" | 1254 | $ firejail "\-\-whitelist=/home/username/My Virtual Machines" |
1253 | .TP | 1255 | .TP |
1254 | \fB\-\-zsh | 1256 | \fB\-\-zsh |