From 87989a94acfa91d4460221b9203cf4f937f58f41 Mon Sep 17 00:00:00 2001 From: sarneaud Date: Fri, 4 Sep 2015 11:51:51 +1000 Subject: Stop blacklisting from traversing . and .. after a glob --- src/firejail/firejail.h | 1 + src/firejail/fs.c | 6 +++++- src/firejail/util.c | 10 ++++++++++ 3 files changed, 16 insertions(+), 1 deletion(-) diff --git a/src/firejail/firejail.h b/src/firejail/firejail.h index d816d42e2..315a8c7f4 100644 --- a/src/firejail/firejail.h +++ b/src/firejail/firejail.h @@ -262,6 +262,7 @@ void update_map(char *mapping, char *map_file); void wait_for_other(int fd); void notify_other(int fd); char *expand_home(const char *path, const char* homedir); +const char *gnu_basename(const char *path); // fs_var.c void fs_var_log(void); // mounting /var/log diff --git a/src/firejail/fs.c b/src/firejail/fs.c index 8632952a4..14c76a144 100644 --- a/src/firejail/fs.c +++ b/src/firejail/fs.c @@ -215,8 +215,12 @@ static void globbing(OPERATION op, const char *pattern, const char *noblacklist[ size_t i, j; for (i = 0; i < globbuf.gl_pathc; i++) { - char* path = globbuf.gl_pathv[i]; + char *path = globbuf.gl_pathv[i]; assert(path); + // /home/me/.* can glob to /home/me/.. which would blacklist /home/ + const char *base = gnu_basename(path); + if (strcmp(base, ".") == 0 || strcmp(base, "..") == 0) + continue; // noblacklist is expected to be short in normal cases, so stupid and correct brute force is okay bool okay_to_blacklist = true; for (j = 0; j < noblacklist_len; j++) { diff --git a/src/firejail/util.c b/src/firejail/util.c index 59b975b4f..a9e96266c 100644 --- a/src/firejail/util.c +++ b/src/firejail/util.c @@ -482,3 +482,13 @@ char *expand_home(const char *path, const char* homedir) return strdup(path); } +// Equivalent to the GNU version of basename, which is incompatible with +// the POSIX basename. A few lines of code saves any portability pain. +// https://www.gnu.org/software/libc/manual/html_node/Finding-Tokens-in-a-String.html#index-basename +const char *gnu_basename(const char *path) +{ + const char *last_slash = strrchr(path, '/'); + if (!last_slash) + return path; + return last_slash+1; +} -- cgit v1.2.3-70-g09d2