Package: release.debian.org Severity: normal User: release.debian....@packages.debian.org Usertags: unblock
Please unblock package firejail Version 0.9.44.8-2 includes a cherry-picked patch that fixes a memory corruption which leads to a crash when firejail is called with certain options (#862083). Kind regards, Reiner unblock firejail/0.9.44.8-2
diff -Nru firejail-0.9.44.8/debian/changelog firejail-0.9.44.8/debian/changelog --- firejail-0.9.44.8/debian/changelog 2017-01-19 23:14:35.000000000 +0100 +++ firejail-0.9.44.8/debian/changelog 2017-05-09 21:15:19.000000000 +0200 @@ -1,3 +1,10 @@ +firejail (0.9.44.8-2) unstable; urgency=medium + + * Cherry-pick upstream patch for memory corruption in noblacklist + processing (Closes: #862083). + + -- Reiner Herrmann <rei...@reiner-h.de> Tue, 09 May 2017 21:15:19 +0200 + firejail (0.9.44.8-1) unstable; urgency=medium * New upstream release. diff -Nru firejail-0.9.44.8/debian/patches/0001-bugfix-ugly-memory-corruption-in-noblacklist-process.patch firejail-0.9.44.8/debian/patches/0001-bugfix-ugly-memory-corruption-in-noblacklist-process.patch --- firejail-0.9.44.8/debian/patches/0001-bugfix-ugly-memory-corruption-in-noblacklist-process.patch 1970-01-01 01:00:00.000000000 +0100 +++ firejail-0.9.44.8/debian/patches/0001-bugfix-ugly-memory-corruption-in-noblacklist-process.patch 2017-05-09 21:10:12.000000000 +0200 @@ -0,0 +1,241 @@ +From: netblue30 <netblu...@yahoo.com> +Subject: [PATCH] bugfix: ugly memory corruption in noblacklist processing +Origin: upstream, https://github.com/netblue30/firejail/commit/ad51fb7489a148ed87abe367a82e0d25203b2d28 +Debian-Bug: https://bugs.debian.org/862083 + +diff --git a/src/firejail/firejail.h b/src/firejail/firejail.h +index 13be6b11..d1445ea3 100644 +--- a/src/firejail/firejail.h ++++ b/src/firejail/firejail.h +@@ -631,6 +631,7 @@ void run_symlink(int argc, char **argv); + + // paths.c + char **build_paths(void); ++unsigned int count_paths(void); + + // fs_mkdir.c + void fs_mkdir(const char *name); +diff --git a/src/firejail/fs.c b/src/firejail/fs.c +index 3ea4725b..3efaae93 100644 +--- a/src/firejail/fs.c ++++ b/src/firejail/fs.c +@@ -436,26 +436,35 @@ void fs_blacklist(void) { + + // Process noblacklist command + if (strncmp(entry->data, "noblacklist ", 12) == 0) { +- char **paths = build_paths(); +- +- char *enames[sizeof(paths)+1] = {0}; +- int i = 0; ++ char **enames; ++ int i; + + if (strncmp(entry->data + 12, "${PATH}", 7) == 0) { + // expand ${PATH} macro +- while (paths[i] != NULL) { +- if (asprintf(&enames[i], "%s%s", paths[i], entry->data + 19) == -1) ++ char **paths = build_paths(); ++ unsigned int npaths = count_paths(); ++ enames = calloc(npaths, sizeof(char *)); ++ if (!enames) ++ errExit("calloc"); ++ ++ for (i = 0; paths[i]; i++) { ++ if (asprintf(&enames[i], "%s%s", paths[i], ++ entry->data + 19) == -1) + errExit("asprintf"); +- i++; + } +- } else { ++ assert(enames[npaths-1] == 0); ++ ++ } ++ else { + // expand ${HOME} macro if found or pass as is ++ enames = calloc(2, sizeof(char *)); ++ if (!enames) ++ errExit("calloc"); + enames[0] = expand_home(entry->data + 12, homedir); +- enames[1] = NULL; ++ assert(enames[1] == 0); + } + +- i = 0; +- while (enames[i] != NULL) { ++ for (i = 0; enames[i]; i++) { + if (noblacklist_c >= noblacklist_m) { + noblacklist_m *= 2; + noblacklist = realloc(noblacklist, sizeof(*noblacklist) * noblacklist_m); +@@ -463,12 +472,9 @@ void fs_blacklist(void) { + errExit("failed increasing memory for noblacklist entries"); + } + noblacklist[noblacklist_c++] = enames[i]; +- i++; + } + +- while (enames[i] != NULL) { +- free(enames[i]); +- } ++ free(enames); + + entry = entry->next; + continue; +diff --git a/src/firejail/paths.c b/src/firejail/paths.c +index 97a1d5a9..b7841226 100644 +--- a/src/firejail/paths.c ++++ b/src/firejail/paths.c +@@ -1,5 +1,5 @@ + /* +- * Copyright (C) 2014-2016 Firejail Authors ++ * Copyright (C) 2014-2017 Firejail Authors + * + * This file is part of firejail project + * +@@ -18,83 +18,78 @@ + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ + #include "firejail.h" ++#include <sys/stat.h> + +-static char **paths = NULL; +-static int path_cnt = 0; +-static char initialized = 0; ++static char **paths = 0; ++static unsigned int path_cnt = 0; ++static unsigned int longest_path_elt = 0; + +-static void add_path(const char *path) { +- assert(paths); +- assert(path_cnt); +- +- // filter out duplicates +- int i; +- int empty = 0; +- for (i = 0; i < path_cnt; i++) { +- if (paths[i] && strcmp(path, paths[i]) == 0) { +- return; +- } +- if (!paths[i]) { +- empty = i; +- break; +- } ++static void init_paths(void) { ++ char *path = getenv("PATH"); ++ char *p; ++ if (!path) { ++ path = "/usr/local/bin:/usr/bin:/bin:/usr/local/sbin:/usr/sbin:/sbin"; ++ setenv("PATH", path, 1); + } +- +- paths[empty] = strdup(path); +- if (!paths[empty]) ++ path = strdup(path); ++ if (!path) + errExit("strdup"); +-} + +-char **build_paths(void) { +- if (initialized) { +- assert(paths); +- return paths; +- } +- initialized = 1; +- +- int cnt = 5; // 4 default paths + 1 NULL to end the array +- char *path1 = getenv("PATH"); +- if (path1) { +- char *path2 = strdup(path1); +- if (!path2) +- errExit("strdup"); +- +- // use path2 to count the entries +- char *ptr = strtok(path2, ":"); +- while (ptr) { +- cnt++; +- ptr = strtok(NULL, ":"); +- } +- free(path2); +- path_cnt = cnt; ++ // size the paths array ++ for (p = path; *p; p++) ++ if (*p == ':') ++ path_cnt++; ++ path_cnt += 2; // one because we were counting fenceposts, one for the NULL at the end ++ ++ paths = calloc(path_cnt, sizeof(char *)); ++ if (!paths) ++ errExit("calloc"); ++ ++ // fill in 'paths' with pointers to elements of 'path' ++ char *elt; ++ unsigned int i = 0, j; ++ unsigned int len; ++ while ((elt = strsep(&path, ":")) != 0) { ++ // skip any entry that is not absolute ++ if (elt[0] != '/') ++ goto skip; ++ ++ // strip trailing slashes (this also prevents '/' from being a path entry). ++ len = strlen(elt); ++ while (len > 0 && elt[len-1] == '/') ++ elt[--len] = '\0'; ++ if (len == 0) ++ goto skip; + +- // allocate paths array +- paths = malloc(sizeof(char *) * cnt); +- if (!paths) +- errExit("malloc"); +- memset(paths, 0, sizeof(char *) * cnt); ++ // filter out duplicate entries ++ for (j = 0; j < i; j++) ++ if (strcmp(elt, paths[j]) == 0) ++ goto skip; + +- // add default paths +- add_path("/usr/local/bin"); +- add_path("/usr/bin"); +- add_path("/bin"); +- add_path("/usr/local/sbin"); +- add_path("/usr/sbin"); +- add_path("/sbin"); ++ paths[i++] = elt; ++ if (len > longest_path_elt) ++ longest_path_elt = len; + +- path2 = strdup(path1); +- if (!path2) +- errExit("strdup"); +- +- // use path2 to count the entries +- ptr = strtok(path2, ":"); +- while (ptr) { +- cnt++; +- add_path(ptr); +- ptr = strtok(NULL, ":"); +- } +- free(path2); ++ skip:; + } +- ++ ++ assert(paths[i] == 0); ++ // path_cnt may be too big now, if entries were skipped above ++ path_cnt = i+1; ++} ++ ++ ++char **build_paths(void) { ++ if (!paths) ++ init_paths(); ++ assert(paths); + return paths; + } ++ ++// Note: the NULL element at the end of 'paths' is included in this count. ++unsigned int count_paths(void) { ++ if (!path_cnt) ++ init_paths(); ++ assert(path_cnt); ++ return path_cnt; ++} diff -Nru firejail-0.9.44.8/debian/patches/series firejail-0.9.44.8/debian/patches/series --- firejail-0.9.44.8/debian/patches/series 1970-01-01 01:00:00.000000000 +0100 +++ firejail-0.9.44.8/debian/patches/series 2017-05-09 21:11:34.000000000 +0200 @@ -0,0 +1 @@ +0001-bugfix-ugly-memory-corruption-in-noblacklist-process.patch