aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorLibravatar netblue30 <netblue30@yahoo.com>2017-03-09 13:51:07 -0500
committerLibravatar netblue30 <netblue30@yahoo.com>2017-03-09 13:51:07 -0500
commitcdde8872a75105b6b347db93315ec0ecd97d6289 (patch)
tree0e3aaf7e0f302d88feb74aa39edd10d1c6f8f156 /src
parentwarning message not terminated by \n (diff)
downloadfirejail-cdde8872a75105b6b347db93315ec0ecd97d6289.tar.gz
firejail-cdde8872a75105b6b347db93315ec0ecd97d6289.tar.zst
firejail-cdde8872a75105b6b347db93315ec0ecd97d6289.zip
--nowhitelist
Diffstat (limited to 'src')
-rw-r--r--src/bash_completion/firejail.bash_completion8
-rw-r--r--src/firejail/firejail.h1
-rw-r--r--src/firejail/fs.c4
-rw-r--r--src/firejail/fs_mkdir.c2
-rw-r--r--src/firejail/fs_whitelist.c146
-rw-r--r--src/firejail/main.c8
-rw-r--r--src/firejail/profile.c2
-rw-r--r--src/firejail/usage.c1
-rw-r--r--src/man/firejail-profile.txt6
-rw-r--r--src/man/firejail.txt4
10 files changed, 140 insertions, 42 deletions
diff --git a/src/bash_completion/firejail.bash_completion b/src/bash_completion/firejail.bash_completion
index 0f71c74dc..38548c42b 100644
--- a/src/bash_completion/firejail.bash_completion
+++ b/src/bash_completion/firejail.bash_completion
@@ -43,10 +43,18 @@ _firejail()
43 _filedir 43 _filedir
44 return 0 44 return 0
45 ;; 45 ;;
46 --noblacklist)
47 _filedir
48 return 0
49 ;;
46 --whitelist) 50 --whitelist)
47 _filedir 51 _filedir
48 return 0 52 return 0
49 ;; 53 ;;
54 --nowhitelist)
55 _filedir
56 return 0
57 ;;
50 --read-only) 58 --read-only)
51 _filedir 59 _filedir
52 return 0 60 return 0
diff --git a/src/firejail/firejail.h b/src/firejail/firejail.h
index a41d5fa17..74e5b2c6b 100644
--- a/src/firejail/firejail.h
+++ b/src/firejail/firejail.h
@@ -650,6 +650,7 @@ void x11_start(int argc, char **argv);
650void x11_start_xpra(int argc, char **argv); 650void x11_start_xpra(int argc, char **argv);
651void x11_start_xephyr(int argc, char **argv); 651void x11_start_xephyr(int argc, char **argv);
652void x11_block(void); 652void x11_block(void);
653void x11_start_xvfb(int argc, char **argv);
653 654
654// ls.c 655// ls.c
655enum { 656enum {
diff --git a/src/firejail/fs.c b/src/firejail/fs.c
index a06f3a35d..712e5fb0a 100644
--- a/src/firejail/fs.c
+++ b/src/firejail/fs.c
@@ -255,7 +255,9 @@ void fs_blacklist(void) {
255 char *ptr; 255 char *ptr;
256 256
257 // whitelist commands handled by fs_whitelist() 257 // whitelist commands handled by fs_whitelist()
258 if (strncmp(entry->data, "whitelist ", 10) == 0 || *entry->data == '\0') { 258 if (strncmp(entry->data, "whitelist ", 10) == 0 ||
259 strncmp(entry->data, "nowhitelist ", 12) == 0 ||
260 *entry->data == '\0') {
259 entry = entry->next; 261 entry = entry->next;
260 continue; 262 continue;
261 } 263 }
diff --git a/src/firejail/fs_mkdir.c b/src/firejail/fs_mkdir.c
index 35d043dde..f90b7df60 100644
--- a/src/firejail/fs_mkdir.c
+++ b/src/firejail/fs_mkdir.c
@@ -57,8 +57,6 @@ static void mkdir_recursive(char *path) {
57 57
58void fs_mkdir(const char *name) { 58void fs_mkdir(const char *name) {
59 EUID_ASSERT(); 59 EUID_ASSERT();
60printf("****************************\n");
61
62 60
63 // check directory name 61 // check directory name
64 invalid_filename(name); 62 invalid_filename(name);
diff --git a/src/firejail/fs_whitelist.c b/src/firejail/fs_whitelist.c
index 1794e4b35..7ad5ffeb8 100644
--- a/src/firejail/fs_whitelist.c
+++ b/src/firejail/fs_whitelist.c
@@ -35,7 +35,7 @@ static char *dentry[] = {
35}; 35};
36 36
37#define MAXBUF 4098 37#define MAXBUF 4098
38static char *resolve_downloads(void) { 38static char *resolve_downloads(int nowhitelist_flag) {
39 char *fname; 39 char *fname;
40 struct stat s; 40 struct stat s;
41 41
@@ -50,8 +50,14 @@ static char *resolve_downloads(void) {
50 printf("Downloads directory resolved as \"%s\"\n", fname); 50 printf("Downloads directory resolved as \"%s\"\n", fname);
51 51
52 char *rv; 52 char *rv;
53 if (asprintf(&rv, "whitelist ~/%s", dentry[i]) == -1) 53 if (nowhitelist_flag) {
54 errExit("asprintf"); 54 if (asprintf(&rv, "nowhitelist ~/%s", dentry[i]) == -1)
55 errExit("asprintf");
56 }
57 else {
58 if (asprintf(&rv, "whitelist ~/%s", dentry[i]) == -1)
59 errExit("asprintf");
60 }
55 free(fname); 61 free(fname);
56 return rv; 62 return rv;
57 } 63 }
@@ -101,8 +107,14 @@ static char *resolve_downloads(void) {
101 } 107 }
102 108
103 char *rv; 109 char *rv;
104 if (asprintf(&rv, "whitelist ~/%s", ptr + 24) == -1) 110 if (nowhitelist_flag) {
105 errExit("asprintf"); 111 if (asprintf(&rv, "nowhitelist ~/%s", ptr + 24) == -1)
112 errExit("asprintf");
113 }
114 else {
115 if (asprintf(&rv, "whitelist ~/%s", ptr + 24) == -1)
116 errExit("asprintf");
117 }
106 return rv; 118 return rv;
107 } 119 }
108 else 120 else
@@ -309,38 +321,54 @@ void fs_whitelist(void) {
309 int var_dir = 0; // /var directory flag 321 int var_dir = 0; // /var directory flag
310 int dev_dir = 0; // /dev directory flag 322 int dev_dir = 0; // /dev directory flag
311 int opt_dir = 0; // /opt directory flag 323 int opt_dir = 0; // /opt directory flag
312 int srv_dir = 0; // /srv directory flag 324 int srv_dir = 0; // /srv directory flag
325
326 size_t nowhitelist_c = 0;
327 size_t nowhitelist_m = 32;
328 char **nowhitelist = calloc(nowhitelist_m, sizeof(*nowhitelist));
329 if (nowhitelist == NULL)
330 errExit("failed allocating memory for nowhitelist entries");
331
313 // verify whitelist files, extract symbolic links, etc. 332 // verify whitelist files, extract symbolic links, etc.
314 while (entry) { 333 while (entry) {
315 // handle only whitelist commands 334 int nowhitelist_flag = 0;
316 if (strncmp(entry->data, "whitelist ", 10)) { 335
336 // handle only whitelist and nowhitelist commands
337 if (strncmp(entry->data, "whitelist ", 10) == 0)
338 nowhitelist_flag = 0;
339 else if (strncmp(entry->data, "nowhitelist ", 12) == 0)
340 nowhitelist_flag = 1;
341 else {
317 entry = entry->next; 342 entry = entry->next;
318 continue; 343 continue;
319 } 344 }
345 char *dataptr = (nowhitelist_flag)? entry->data + 12: entry->data + 10;
320 346
321 // resolve ${DOWNLOADS} 347 // resolve ${DOWNLOADS}
322 if (strcmp(entry->data + 10, "${DOWNLOADS}") == 0) { 348 if (strcmp(dataptr, "${DOWNLOADS}") == 0) {
323 char *tmp = resolve_downloads(); 349 char *tmp = resolve_downloads(nowhitelist_flag);
324 if (tmp) 350 if (tmp) {
325 entry->data = tmp; 351 entry->data = tmp;
352 dataptr = (nowhitelist_flag)? entry->data + 12: entry->data + 10;
353 }
326 else { 354 else {
355 if (!nowhitelist_flag) {
356 fprintf(stderr, "***\n");
357 fprintf(stderr, "*** Warning: cannot whitelist Downloads directory\n");
358 fprintf(stderr, "*** \tAny file saved will be lost when the sandbox is closed.\n");
359 fprintf(stderr, "*** \tPlease create a proper Downloads directory for your application.\n");
360 fprintf(stderr, "***\n");
361 }
327 *entry->data = '\0'; 362 *entry->data = '\0';
328 fprintf(stderr, "***\n");
329 fprintf(stderr, "*** Warning: cannot whitelist Downloads directory\n");
330 fprintf(stderr, "*** \tAny file saved will be lost when the sandbox is closed.\n");
331 fprintf(stderr, "*** \tPlease create a proper Downloads directory for your application.\n");
332 fprintf(stderr, "***\n");
333 continue; 363 continue;
334 } 364 }
335 } 365 }
336 366
337 // replace ~/ or ${HOME} into /home/username 367 // replace ~/ or ${HOME} into /home/username
338// if (new_name) 368 new_name = expand_home(dataptr, cfg.homedir);
339// free(new_name);
340 new_name = expand_home(entry->data + 10, cfg.homedir);
341 assert(new_name); 369 assert(new_name);
342 if (arg_debug) 370 if (arg_debug)
343 fprintf(stderr, "Debug %d: new_name #%s#\n", __LINE__, new_name); 371 fprintf(stderr, "Debug %d: new_name #%s#, %s\n", __LINE__, new_name, (nowhitelist_flag)? "nowhitelist": "whitelist");
344 372
345 // valid path referenced to filesystem root 373 // valid path referenced to filesystem root
346 if (*new_name != '/') { 374 if (*new_name != '/') {
@@ -356,37 +384,56 @@ void fs_whitelist(void) {
356 if (!fname) { 384 if (!fname) {
357 // file not found, blank the entry in the list and continue 385 // file not found, blank the entry in the list and continue
358 if (arg_debug || arg_debug_whitelists) { 386 if (arg_debug || arg_debug_whitelists) {
359 printf("Removed whitelist path: %s\n", entry->data); 387 printf("Removed whitelist/nowhitelist path: %s\n", entry->data);
360 printf("\texpanded: %s\n", new_name); 388 printf("\texpanded: %s\n", new_name);
361 printf("\treal path: (null)\n"); 389 printf("\treal path: (null)\n");
362 printf("\t");fflush(0); 390 printf("\t");fflush(0);
363 perror("realpath"); 391 perror("realpath");
364 } 392 }
365 *entry->data = '\0';
366 393
367 // if 1 the file was not found; mount an empty directory 394 // if 1 the file was not found; mount an empty directory
368 if (strncmp(new_name, cfg.homedir, strlen(cfg.homedir)) == 0) { 395 if (!nowhitelist_flag) {
369 if(!arg_private) 396 if (strncmp(new_name, cfg.homedir, strlen(cfg.homedir)) == 0) {
370 home_dir = 1; 397 if(!arg_private)
398 home_dir = 1;
399 }
400 else if (strncmp(new_name, "/tmp/", 5) == 0)
401 tmp_dir = 1;
402 else if (strncmp(new_name, "/media/", 7) == 0)
403 media_dir = 1;
404 else if (strncmp(new_name, "/mnt/", 5) == 0)
405 mnt_dir = 1;
406 else if (strncmp(new_name, "/var/", 5) == 0)
407 var_dir = 1;
408 else if (strncmp(new_name, "/dev/", 5) == 0)
409 dev_dir = 1;
410 else if (strncmp(new_name, "/opt/", 5) == 0)
411 opt_dir = 1;
412 else if (strncmp(new_name, "/srv/", 5) == 0)
413 opt_dir = 1;
371 } 414 }
372 else if (strncmp(new_name, "/tmp/", 5) == 0)
373 tmp_dir = 1;
374 else if (strncmp(new_name, "/media/", 7) == 0)
375 media_dir = 1;
376 else if (strncmp(new_name, "/mnt/", 5) == 0)
377 mnt_dir = 1;
378 else if (strncmp(new_name, "/var/", 5) == 0)
379 var_dir = 1;
380 else if (strncmp(new_name, "/dev/", 5) == 0)
381 dev_dir = 1;
382 else if (strncmp(new_name, "/opt/", 5) == 0)
383 opt_dir = 1;
384 else if (strncmp(new_name, "/srv/", 5) == 0)
385 opt_dir = 1;
386 415
416 *entry->data = '\0';
417 continue;
418 }
419
420 if (nowhitelist_flag) {
421 // store the path in nowhitelist array
422 if (arg_debug || arg_debug_whitelists)
423 printf("Storing nowhitelist %s\n", fname);
424
425 if (nowhitelist_c >= nowhitelist_m) {
426 nowhitelist_m *= 2;
427 nowhitelist = realloc(nowhitelist, sizeof(*nowhitelist) * nowhitelist_m);
428 if (nowhitelist == NULL)
429 errExit("failed increasing memory for nowhitelist entries");
430 }
431 nowhitelist[nowhitelist_c++] = fname;
432 *entry->data = 0;
387 continue; 433 continue;
388 } 434 }
389 435
436
390 // check for supported directories 437 // check for supported directories
391 if (strncmp(new_name, cfg.homedir, strlen(cfg.homedir)) == 0) { 438 if (strncmp(new_name, cfg.homedir, strlen(cfg.homedir)) == 0) {
392 // whitelisting home directory is disabled if --private option is present 439 // whitelisting home directory is disabled if --private option is present
@@ -479,6 +526,27 @@ void fs_whitelist(void) {
479 goto errexit; 526 goto errexit;
480 } 527 }
481 528
529 // check if the path is in nowhitelist array
530 if (nowhitelist_flag == 0) {
531 size_t i;
532 int found = 0;
533 for (i = 0; i < nowhitelist_c; i++) {
534 if (nowhitelist[i] == NULL)
535 break;
536 if (strcmp(nowhitelist[i], fname) == 0) {
537 found = 1;
538 break;
539 }
540 }
541 if (found) {
542 if (arg_debug || arg_debug_whitelists)
543 printf("Skip nowhitelisted path %s\n", fname);
544 *entry->data = 0;
545 free(fname);
546 continue;
547 }
548 }
549
482 // mark symbolic links 550 // mark symbolic links
483 if (is_link(new_name)) 551 if (is_link(new_name))
484 entry->link = new_name; 552 entry->link = new_name;
diff --git a/src/firejail/main.c b/src/firejail/main.c
index 5951e5d16..aead29957 100644
--- a/src/firejail/main.c
+++ b/src/firejail/main.c
@@ -1269,6 +1269,14 @@ int main(int argc, char **argv) {
1269 else 1269 else
1270 exit_err_feature("whitelist"); 1270 exit_err_feature("whitelist");
1271 } 1271 }
1272 else if (strncmp(argv[i], "--nowhitelist=", 14) == 0) {
1273 char *line;
1274 if (asprintf(&line, "nowhitelist %s", argv[i] + 14) == -1)
1275 errExit("asprintf");
1276
1277 profile_check_line(line, 0, NULL); // will exit if something wrong
1278 profile_add(line);
1279 }
1272#endif 1280#endif
1273 1281
1274 else if (strncmp(argv[i], "--read-only=", 12) == 0) { 1282 else if (strncmp(argv[i], "--read-only=", 12) == 0) {
diff --git a/src/firejail/profile.c b/src/firejail/profile.c
index 9f6688d4a..c4feadad0 100644
--- a/src/firejail/profile.c
+++ b/src/firejail/profile.c
@@ -960,6 +960,8 @@ int profile_check_line(char *ptr, int lineno, const char *fname) {
960 return 0; 960 return 0;
961#endif 961#endif
962 } 962 }
963 else if (strncmp(ptr, "nowhitelist ", 12) == 0)
964 ptr += 12;
963 else if (strncmp(ptr, "read-only ", 10) == 0) 965 else if (strncmp(ptr, "read-only ", 10) == 0)
964 ptr += 10; 966 ptr += 10;
965 else if (strncmp(ptr, "read-write ", 11) == 0) 967 else if (strncmp(ptr, "read-write ", 11) == 0)
diff --git a/src/firejail/usage.c b/src/firejail/usage.c
index 4d2054a72..9c91b4630 100644
--- a/src/firejail/usage.c
+++ b/src/firejail/usage.c
@@ -127,6 +127,7 @@ void usage(void) {
127 printf(" --noroot - install a user namespace with only the current user.\n"); 127 printf(" --noroot - install a user namespace with only the current user.\n");
128#endif 128#endif
129 printf(" --nonewprivs - sets the NO_NEW_PRIVS prctl.\n"); 129 printf(" --nonewprivs - sets the NO_NEW_PRIVS prctl.\n");
130 printf(" --nowhitelist=filename - disable whitelist for file or directory .\n");
130 printf(" --output=logfile - stdout logging and log rotation.\n"); 131 printf(" --output=logfile - stdout logging and log rotation.\n");
131 printf(" --overlay - mount a filesystem overlay on top of the current filesystem.\n"); 132 printf(" --overlay - mount a filesystem overlay on top of the current filesystem.\n");
132 printf(" --overlay-named=name - mount a filesystem overlay on top of the current\n"); 133 printf(" --overlay-named=name - mount a filesystem overlay on top of the current\n");
diff --git a/src/man/firejail-profile.txt b/src/man/firejail-profile.txt
index cf2398ad4..76cd4d4fa 100644
--- a/src/man/firejail-profile.txt
+++ b/src/man/firejail-profile.txt
@@ -103,6 +103,12 @@ If the file name matches file_name, the file will not be blacklisted in any blac
103Example: "noblacklist ${HOME}/.mozilla" 103Example: "noblacklist ${HOME}/.mozilla"
104 104
105.TP 105.TP
106\fBnowhitelist file_name
107If the file name matches file_name, the file will not be whitelisted in any whitelist commands that follow.
108
109Example: "nowhitelist ~/.config"
110
111.TP
106\fBignore 112\fBignore
107Ignore command. 113Ignore command.
108 114
diff --git a/src/man/firejail.txt b/src/man/firejail.txt
index 2b6069a7a..f603daecb 100644
--- a/src/man/firejail.txt
+++ b/src/man/firejail.txt
@@ -1067,6 +1067,10 @@ Example:
1067$ firejail \-\-nosound firefox 1067$ firejail \-\-nosound firefox
1068 1068
1069.TP 1069.TP
1070\fB\-\-nowhitelist=dirname_or_filename
1071Disable whitelist for this directory or file.
1072
1073.TP
1070\fB\-\-output=logfile 1074\fB\-\-output=logfile
1071stdout logging and log rotation. Copy stdout and stderr to logfile, and keep the size of the file under 500KB using log 1075stdout logging and log rotation. Copy stdout and stderr to logfile, and keep the size of the file under 500KB using log
1072rotation. Five files with prefixes .1 to .5 are used in rotation. 1076rotation. Five files with prefixes .1 to .5 are used in rotation.