aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLibravatar smitsohu <smitsohu@gmail.com>2021-03-25 15:14:36 +0100
committerLibravatar smitsohu <smitsohu@gmail.com>2021-03-25 17:20:08 +0100
commit2295b1c91a32a56f34209ca40a4a9c1bddbdbdd2 (patch)
tree62ba3324880de1739d070f299ce138ca91888b35
parentfix hardening comment (diff)
downloadfirejail-2295b1c91a32a56f34209ca40a4a9c1bddbdbdd2.tar.gz
firejail-2295b1c91a32a56f34209ca40a4a9c1bddbdbdd2.tar.zst
firejail-2295b1c91a32a56f34209ca40a4a9c1bddbdbdd2.zip
private-lib: trim ending slashes and dots
Currently pathological endings like in /foo/bar/./. are mapped to RUN_LIB_DIR, with the effect that the mount is skipped because this directory always exists at this point in time. Even though it's harmless, it is wrong behaviour, so handle trailing slashes and dots before doing the mounts. Also avoids running into an assertion if there is a trailing slash. Plus few small cosmetic changes to make things more explicit.
-rw-r--r--src/firejail/fs_lib.c24
1 files changed, 18 insertions, 6 deletions
diff --git a/src/firejail/fs_lib.c b/src/firejail/fs_lib.c
index 0491fd9b1..85fb70854 100644
--- a/src/firejail/fs_lib.c
+++ b/src/firejail/fs_lib.c
@@ -52,8 +52,9 @@ static int valid_full_path(const char *full_path) {
52 52
53 int i = 0; 53 int i = 0;
54 while (masked_lib_dirs[i]) { 54 while (masked_lib_dirs[i]) {
55 if (strncmp(full_path, masked_lib_dirs[i], strlen(masked_lib_dirs[i])) == 0 && 55 size_t len = strlen(masked_lib_dirs[i]);
56 full_path[strlen(masked_lib_dirs[i])] == '/') 56 if (strncmp(full_path, masked_lib_dirs[i], len) == 0 &&
57 full_path[len] == '/')
57 return 1; 58 return 1;
58 i++; 59 i++;
59 } 60 }
@@ -120,7 +121,8 @@ static char *build_dest_name(const char *full_path) {
120 char *fname = strrchr(full_path, '/'); 121 char *fname = strrchr(full_path, '/');
121 assert(fname); 122 assert(fname);
122 fname++; 123 fname++;
123 assert(*fname != '\0'); 124 // no trailing slash or dot
125 assert(fname[0] != '\0' && (fname[0] != '.' || fname[1] != '\0'));
124 126
125 char *dest; 127 char *dest;
126 if (asprintf(&dest, "%s/%s", build_dest_dir(full_path), fname) == -1) 128 if (asprintf(&dest, "%s/%s", build_dest_dir(full_path), fname) == -1)
@@ -174,7 +176,8 @@ void fslib_mount(const char *full_path) {
174 assert(full_path); 176 assert(full_path);
175 struct stat s; 177 struct stat s;
176 178
177 if (!valid_full_path(full_path) || 179 if (*full_path == '\0' ||
180 !valid_full_path(full_path) ||
178 access(full_path, F_OK) != 0 || 181 access(full_path, F_OK) != 0 ||
179 stat(full_path, &s) != 0 || 182 stat(full_path, &s) != 0 ||
180 s.st_uid != 0) 183 s.st_uid != 0)
@@ -229,13 +232,14 @@ void fslib_mount_libs(const char *full_path, unsigned user) {
229 if (ptr) 232 if (ptr)
230 *ptr = '\0'; 233 *ptr = '\0';
231 234
235 trim_trailing_slash_or_dot(buf);
232 fslib_mount(buf); 236 fslib_mount(buf);
233 } 237 }
234 fclose(fp); 238 fclose(fp);
235 unlink(RUN_LIB_FILE); 239 unlink(RUN_LIB_FILE);
236} 240}
237 241
238// fname should be a valid full path at this point 242// fname should be a full path at this point
239static void load_library(const char *fname) { 243static void load_library(const char *fname) {
240 assert(fname); 244 assert(fname);
241 assert(*fname == '/'); 245 assert(*fname == '/');
@@ -293,6 +297,11 @@ static void install_list_entry(const char *lib) {
293 assert(globbuf.gl_pathv[j]); 297 assert(globbuf.gl_pathv[j]);
294//printf("glob %s\n", globbuf.gl_pathv[j]); 298//printf("glob %s\n", globbuf.gl_pathv[j]);
295 // GLOB_NOCHECK - no pattern matched returns the original pattern; try to load it anyway 299 // GLOB_NOCHECK - no pattern matched returns the original pattern; try to load it anyway
300
301 // foobar/* includes foobar/. and foobar/..
302 const char *base = gnu_basename(globbuf.gl_pathv[j]);
303 if (strcmp(base, ".") == 0 || strcmp(base, "..") == 0)
304 continue;
296 load_library(globbuf.gl_pathv[j]); 305 load_library(globbuf.gl_pathv[j]);
297 } 306 }
298 307
@@ -321,10 +330,13 @@ void fslib_install_list(const char *lib_list) {
321 fprintf(stderr, "Error: invalid private-lib argument\n"); 330 fprintf(stderr, "Error: invalid private-lib argument\n");
322 exit(1); 331 exit(1);
323 } 332 }
333 trim_trailing_slash_or_dot(ptr);
324 install_list_entry(ptr); 334 install_list_entry(ptr);
325 335
326 while ((ptr = strtok(NULL, ",")) != NULL) 336 while ((ptr = strtok(NULL, ",")) != NULL) {
337 trim_trailing_slash_or_dot(ptr);
327 install_list_entry(ptr); 338 install_list_entry(ptr);
339 }
328 free(dlist); 340 free(dlist);
329 fs_logger_print(); 341 fs_logger_print();
330} 342}