aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorLibravatar smitsohu <smitsohu@gmail.com>2018-08-04 16:05:07 +0200
committerLibravatar smitsohu <smitsohu@gmail.com>2018-08-04 16:05:07 +0200
commit09296743221b5442a69c61a870170a22d1f835fc (patch)
treef39e8367eb8513ffb22749127837ef72cce53dde /src
parentMerge branch 'master' of https://github.com/netblue30/firejail (diff)
downloadfirejail-09296743221b5442a69c61a870170a22d1f835fc.tar.gz
firejail-09296743221b5442a69c61a870170a22d1f835fc.tar.zst
firejail-09296743221b5442a69c61a870170a22d1f835fc.zip
automatically trim trailing slashes for whitelisting, fix mountinfo test
Command-line autocompletion adds a trailing slash to directories, which leads to a usability problem for whitelisting. So before doing any path validation it is attempted to trim trailing slashes and dots.
Diffstat (limited to 'src')
-rw-r--r--src/firejail/fs_whitelist.c34
1 files changed, 20 insertions, 14 deletions
diff --git a/src/firejail/fs_whitelist.c b/src/firejail/fs_whitelist.c
index 8d7d45c13..74ca8ac25 100644
--- a/src/firejail/fs_whitelist.c
+++ b/src/firejail/fs_whitelist.c
@@ -29,8 +29,7 @@
29 29
30// mountinfo functionality test; 30// mountinfo functionality test;
31// 1. enable TEST_MOUNTINFO definition 31// 1. enable TEST_MOUNTINFO definition
32// 2. set a symlink in /tmp: ln -s /etc /tmp/etc 32// 2. run firejail --whitelist=/any/directory
33// 3. run firejail --debug --whitelist=/tmp/etc
34//#define TEST_MOUNTINFO 33//#define TEST_MOUNTINFO
35 34
36#define EMPTY_STRING ("") 35#define EMPTY_STRING ("")
@@ -218,7 +217,6 @@ static void whitelist_path(ProfileEntry *entry) {
218 217
219 // confirm again the mount source exists and there is no symlink 218 // confirm again the mount source exists and there is no symlink
220 struct stat wfilestat; 219 struct stat wfilestat;
221#ifndef TEST_MOUNTINFO
222 EUID_USER(); 220 EUID_USER();
223 int fd = safe_fd(wfile, O_PATH|O_NOFOLLOW|O_CLOEXEC); 221 int fd = safe_fd(wfile, O_PATH|O_NOFOLLOW|O_CLOEXEC);
224 EUID_ROOT(); 222 EUID_ROOT();
@@ -237,6 +235,10 @@ static void whitelist_path(ProfileEntry *entry) {
237 free(wfile); 235 free(wfile);
238 return; 236 return;
239 } 237 }
238
239#ifdef TEST_MOUNTINFO
240 printf("TEST_MOUNTINFO\n");
241 path = "/etc/.";
240#endif 242#endif
241 243
242 // create path of the mount target if necessary 244 // create path of the mount target if necessary
@@ -557,6 +559,21 @@ void fs_whitelist(void) {
557 // replace ~/ or ${HOME} into /home/username 559 // replace ~/ or ${HOME} into /home/username
558 new_name = expand_home(dataptr, cfg.homedir); 560 new_name = expand_home(dataptr, cfg.homedir);
559 assert(new_name); 561 assert(new_name);
562
563 // trim trailing slashes or dots
564 char *end = strrchr(new_name, '\0');
565 assert(end);
566 if ((end - new_name) > 1) {
567 end--;
568 while (*end == '/' ||
569 (*end == '.' && *(end - 1) == '/')) {
570 *end = '\0';
571 end--;
572 if (end == new_name)
573 break;
574 }
575 }
576
560 if (arg_debug || arg_debug_whitelists) 577 if (arg_debug || arg_debug_whitelists)
561 fprintf(stderr, "Debug %d: new_name #%s#, %s\n", __LINE__, new_name, (nowhitelist_flag)? "nowhitelist": "whitelist"); 578 fprintf(stderr, "Debug %d: new_name #%s#, %s\n", __LINE__, new_name, (nowhitelist_flag)? "nowhitelist": "whitelist");
562 579
@@ -567,15 +584,6 @@ void fs_whitelist(void) {
567 goto errexit; 584 goto errexit;
568 } 585 }
569 586
570 // no trailing slash and no trailing dot
571 char *p = strrchr(new_name, '/');
572 if (!p)
573 errExit("strrchr");
574 if (*(p + 1) == '\0')
575 goto errexit;
576 if (*(p + 1) == '.' && *(p + 2) == '\0')
577 goto errexit;
578
579 // extract the absolute path of the file 587 // extract the absolute path of the file
580 // realpath function will fail with ENOENT if the file is not found 588 // realpath function will fail with ENOENT if the file is not found
581 // special processing for /dev/fd, /dev/stdin, /dev/stdout and /dev/stderr 589 // special processing for /dev/fd, /dev/stdin, /dev/stdout and /dev/stderr
@@ -686,12 +694,10 @@ void fs_whitelist(void) {
686 entry->tmp_dir = 1; 694 entry->tmp_dir = 1;
687 tmp_dir = 1; 695 tmp_dir = 1;
688 696
689#ifndef TEST_MOUNTINFO
690 // both path and absolute path are under /tmp 697 // both path and absolute path are under /tmp
691 if (strncmp(fname, "/tmp/", 5) != 0) { 698 if (strncmp(fname, "/tmp/", 5) != 0) {
692 goto errexit; 699 goto errexit;
693 } 700 }
694#endif
695 } 701 }
696 else if (strncmp(new_name, "/media/", 7) == 0) { 702 else if (strncmp(new_name, "/media/", 7) == 0) {
697 entry->media_dir = 1; 703 entry->media_dir = 1;