aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLibravatar LaurentGH <31282893+LaurentGH@users.noreply.github.com>2017-08-24 15:35:05 +0200
committerLibravatar GitHub <noreply@github.com>2017-08-24 15:35:05 +0200
commite1a24494343016d00100e5e8e7e8716ac77363f6 (patch)
treeeecbefc04d738e98907945a8af818fbf9691a873
parentfix compiling when seccomp is disabled (diff)
downloadfirejail-e1a24494343016d00100e5e8e7e8716ac77363f6.tar.gz
firejail-e1a24494343016d00100e5e8e7e8716ac77363f6.tar.zst
firejail-e1a24494343016d00100e5e8e7e8716ac77363f6.zip
Allow private-bin parameters to be an absolute path
With Ubuntu 16.04, /usr/bin/which is a symlink to /bin/which. So, using "private-bin which" finds "which" in /usr/bin and adds the symlink to "which" in /bin mapped directory. The /bin directory thus contains a symlink named "which" pointing to "/bin/which" (itself). This creates a symlink loop, and does not work. In order to solve this, the full path can now be used, such as "private-bin /bin/which".
-rw-r--r--src/firejail/fs_bin.c30
1 files changed, 22 insertions, 8 deletions
diff --git a/src/firejail/fs_bin.c b/src/firejail/fs_bin.c
index f70bd095b..b4755f755 100644
--- a/src/firejail/fs_bin.c
+++ b/src/firejail/fs_bin.c
@@ -95,20 +95,34 @@ static char *check_dir_or_file(const char *name) {
95} 95}
96 96
97static void duplicate(char *fname, FILE *fplist) { 97static void duplicate(char *fname, FILE *fplist) {
98 if (*fname == '~' || *fname == '/' || strstr(fname, "..")) { 98 if (*fname == '~' || strstr(fname, "..")) {
99 fprintf(stderr, "Error: \"%s\" is an invalid filename\n", fname); 99 fprintf(stderr, "Error: \"%s\" is an invalid filename\n", fname);
100 exit(1); 100 exit(1);
101 } 101 }
102 invalid_filename(fname); 102 invalid_filename(fname);
103 103
104 char *path = check_dir_or_file(fname);
105 if (!path)
106 return;
107
108 // expand path, just in case this is a symbolic link
109 char *full_path; 104 char *full_path;
110 if (asprintf(&full_path, "%s/%s", path, fname) == -1) 105 if (*fname == '/') {
111 errExit("asprintf"); 106 // If the absolute filename is indicated, directly use it. This
107 // is required for the following three cases:
108 // - if user's $PATH order is not the same as the above
109 // paths[] variable order
110 // - if for example /usr/bin/which is a symlink to /bin/which,
111 // because in this case the result is a symlink pointing to
112 // itself due to the file name being the same.
113 // - if user wants to add a binary, which is not in the above
114 // paths[] variable
115 if (asprintf(&full_path, "%s", fname) == -1)
116 errExit("asprintf");
117 } else {
118 // Find the standard directory (by looping through paths[])
119 // where the filename fname is located
120 char *path = check_dir_or_file(fname);
121 if (!path)
122 return;
123 if (asprintf(&full_path, "%s/%s", path, fname) == -1)
124 errExit("asprintf");
125 }
112 126
113 if (fplist) 127 if (fplist)
114 fprintf(fplist, "%s\n", full_path); 128 fprintf(fplist, "%s\n", full_path);