aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/firejail/firejail.h1
-rw-r--r--src/firejail/fs_whitelist.c15
-rw-r--r--src/firejail/util.c33
3 files changed, 36 insertions, 13 deletions
diff --git a/src/firejail/firejail.h b/src/firejail/firejail.h
index f31d6a2bc..5ce380503 100644
--- a/src/firejail/firejail.h
+++ b/src/firejail/firejail.h
@@ -515,6 +515,7 @@ void copy_file_from_user_to_root(const char *srcname, const char *destname, uid_
515void touch_file_as_user(const char *fname, uid_t uid, gid_t gid, mode_t mode); 515void touch_file_as_user(const char *fname, uid_t uid, gid_t gid, mode_t mode);
516int is_dir(const char *fname); 516int is_dir(const char *fname);
517int is_link(const char *fname); 517int is_link(const char *fname);
518void trim_trailing_slash_or_dot(char *path);
518char *line_remove_spaces(const char *buf); 519char *line_remove_spaces(const char *buf);
519char *split_comma(char *str); 520char *split_comma(char *str);
520void check_unsigned(const char *str, const char *msg); 521void check_unsigned(const char *str, const char *msg);
diff --git a/src/firejail/fs_whitelist.c b/src/firejail/fs_whitelist.c
index c3d34e259..602985b4e 100644
--- a/src/firejail/fs_whitelist.c
+++ b/src/firejail/fs_whitelist.c
@@ -395,19 +395,8 @@ void fs_whitelist(void) {
395 new_name = expand_home(dataptr, cfg.homedir); 395 new_name = expand_home(dataptr, cfg.homedir);
396 assert(new_name); 396 assert(new_name);
397 397
398 // trim trailing slashes or dots 398 // remove trailing slashes and single dots
399 char *end = strchr(new_name, '\0'); 399 trim_trailing_slash_or_dot(new_name);
400 assert(end);
401 if ((end - new_name) > 1) {
402 end--;
403 while (*end == '/' ||
404 (*end == '.' && *(end - 1) == '/')) {
405 *end = '\0';
406 end--;
407 if (end == new_name)
408 break;
409 }
410 }
411 400
412 if (arg_debug || arg_debug_whitelists) 401 if (arg_debug || arg_debug_whitelists)
413 fprintf(stderr, "Debug %d: new_name #%s#, %s\n", __LINE__, new_name, (nowhitelist_flag)? "nowhitelist": "whitelist"); 402 fprintf(stderr, "Debug %d: new_name #%s#, %s\n", __LINE__, new_name, (nowhitelist_flag)? "nowhitelist": "whitelist");
diff --git a/src/firejail/util.c b/src/firejail/util.c
index 329ae141b..6db92b554 100644
--- a/src/firejail/util.c
+++ b/src/firejail/util.c
@@ -425,15 +425,48 @@ int is_link(const char *fname) {
425 if (*fname == '\0') 425 if (*fname == '\0')
426 return 0; 426 return 0;
427 427
428 char *dup = NULL;
428 struct stat s; 429 struct stat s;
429 if (lstat(fname, &s) == 0) { 430 if (lstat(fname, &s) == 0) {
430 if (S_ISLNK(s.st_mode)) 431 if (S_ISLNK(s.st_mode))
431 return 1; 432 return 1;
433 if (S_ISDIR(s.st_mode)) {
434 // remove trailing slashes and single dots and try again
435 dup = strdup(fname);
436 if (!dup)
437 errExit("strdup");
438 trim_trailing_slash_or_dot(dup);
439 if (lstat(dup, &s) == 0) {
440 if (S_ISLNK(s.st_mode)) {
441 free(dup);
442 return 1;
443 }
444 }
445 }
432 } 446 }
433 447
448 free(dup);
434 return 0; 449 return 0;
435} 450}
436 451
452// remove all slashes and single dots from the end of a path
453// for example /foo/bar///././. -> /foo/bar
454void trim_trailing_slash_or_dot(char *path) {
455 assert(path);
456
457 char *end = strchr(path, '\0');
458 assert(end);
459 if ((end - path) > 1) {
460 end--;
461 while (*end == '/' ||
462 (*end == '.' && *(end - 1) == '/')) {
463 *end = '\0';
464 end--;
465 if (end == path)
466 break;
467 }
468 }
469}
437 470
438// remove multiple spaces and return allocated memory 471// remove multiple spaces and return allocated memory
439char *line_remove_spaces(const char *buf) { 472char *line_remove_spaces(const char *buf) {