aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--README1
-rw-r--r--README.md4
-rw-r--r--RELNOTES1
-rw-r--r--src/firejail/firejail.h8
-rw-r--r--src/firejail/fs_whitelist.c121
-rw-r--r--src/man/firejail.txt4
6 files changed, 136 insertions, 3 deletions
diff --git a/README b/README
index 5f03b4af3..961cb0497 100644
--- a/README
+++ b/README
@@ -54,6 +54,7 @@ Reiner Herrmann
54 - a number of build patches 54 - a number of build patches
55 - man page fixes 55 - man page fixes
56 - Debian and Ubuntu integration 56 - Debian and Ubuntu integration
57 - clang-analyzer fixes
57sshirokov (http://sourceforge.net/u/yshirokov/profile/) 58sshirokov (http://sourceforge.net/u/yshirokov/profile/)
58 - Patch to output "Reading profile" to stderr instead of stdout 59 - Patch to output "Reading profile" to stderr instead of stdout
59G4JC (http://sourceforge.net/u/gaming4jc/profile/) 60G4JC (http://sourceforge.net/u/gaming4jc/profile/)
diff --git a/README.md b/README.md
index 63086c7dd..578890b1c 100644
--- a/README.md
+++ b/README.md
@@ -84,3 +84,7 @@ New profiles introduced in this version: unbound, dnscrypt-proxy
84 $ nc dict.org 2628 84 $ nc dict.org 2628
85 220 pan.alephnull.com dictd 1.12.1/rf on Linux 3.14-1-amd64 85 220 pan.alephnull.com dictd 1.12.1/rf on Linux 3.14-1-amd64
86````` 86`````
87
88### --whitelist
89
90Whitelist command accepts files in user home, /dev, /media, /var, and /tmp directories.
diff --git a/RELNOTES b/RELNOTES
index 90158583a..731f03eb7 100644
--- a/RELNOTES
+++ b/RELNOTES
@@ -1,6 +1,7 @@
1firejail (0.9.34) baseline; urgency=low 1firejail (0.9.34) baseline; urgency=low
2 * added unbound and dnscrypt-proxy profiles 2 * added unbound and dnscrypt-proxy profiles
3 * added --noblacklist option 3 * added --noblacklist option
4 * whitelist command enhancements
4 * bugfixes 5 * bugfixes
5 -- netblue30 <netblue30@yahoo.com> ongoing development 6 -- netblue30 <netblue30@yahoo.com> ongoing development
6 7
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
98typedef struct config_t { 106typedef 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
1241firejail version 0.9.27 1241firejail version 0.9.27
1242.TP 1242.TP
1243\fB\-\-whitelist=dirname_or_filename 1243\fB\-\-whitelist=dirname_or_filename
1244Whitelist directory or file. Only files in user home directory are accepted. 1244Whitelist 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