From a5b7a9a8bec6a7f2162850449b1ff29c1fde2826 Mon Sep 17 00:00:00 2001 From: smitsohu Date: Fri, 12 Oct 2018 18:33:17 +0200 Subject: clean homedir pathname fixes #2137 and similar issues with the /proc/self/mountinfo checks --- src/firejail/firejail.h | 1 + src/firejail/main.c | 5 ++--- src/firejail/util.c | 42 +++++++++++++++++++++++++++++++++++++++++- 3 files changed, 44 insertions(+), 4 deletions(-) diff --git a/src/firejail/firejail.h b/src/firejail/firejail.h index 1d74dc8dc..cae767667 100644 --- a/src/firejail/firejail.h +++ b/src/firejail/firejail.h @@ -522,6 +522,7 @@ int is_link(const char *fname); void trim_trailing_slash_or_dot(char *path); char *line_remove_spaces(const char *buf); char *split_comma(char *str); +char *clean_pathname(const char *path); void check_unsigned(const char *str, const char *msg); int find_child(pid_t parent, pid_t *child); void check_private_dir(void); diff --git a/src/firejail/main.c b/src/firejail/main.c index 123fe96a1..315a7260a 100644 --- a/src/firejail/main.c +++ b/src/firejail/main.c @@ -233,9 +233,8 @@ static void init_cfg(int argc, char **argv) { // build home directory name cfg.homedir = NULL; if (pw->pw_dir != NULL) { - cfg.homedir = strdup(pw->pw_dir); - if (!cfg.homedir) - errExit("strdup"); + cfg.homedir = clean_pathname(pw->pw_dir); + assert(cfg.homedir); } else { fprintf(stderr, "Error: user %s doesn't have a user directory assigned\n", cfg.username); diff --git a/src/firejail/util.c b/src/firejail/util.c index ae07a42b0..0d1418b43 100644 --- a/src/firejail/util.c +++ b/src/firejail/util.c @@ -533,6 +533,46 @@ char *split_comma(char *str) { } +// remove consecutive and trailing slashes +// and return allocated memory +// e.g. /home//user/ -> /home/user +char *clean_pathname(const char *path) { + assert(path); + size_t len = strlen(path); + char *rv = calloc(len + 1, 1); + if (!rv) + errExit("calloc"); + + if (len > 0) { + int i, j, cnt; + for (i = 0, j = 0, cnt = 0; i < len; i++) { + if (path[i] == '/') + cnt++; + else + cnt = 0; + + if (cnt < 2) { + rv[j] = path[i]; + j++; + } + } + + // remove a trailing slash + if (j > 1 && rv[j - 1] == '/') + rv[j - 1] = '\0'; + + size_t new_len = strlen(rv); + if (new_len < len) { + rv = realloc(rv, new_len + 1); + if (!rv) + errExit("realloc"); + } + } + + return rv; +} + + void check_unsigned(const char *str, const char *msg) { EUID_ASSERT(); const char *ptr = str; @@ -656,7 +696,7 @@ void extract_command_name(int index, char **argv) { // command name is a substring of cfg.command_name if (basename != cfg.command_name || *ptr != '\0') { *ptr = '\0'; - + basename = strdup(basename); if (!basename) errExit("strdup"); -- cgit v1.2.3-70-g09d2