--- Begin Message ---
Package: release.debian.org
Severity: normal
User: release.debian.org@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 <reiner@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 <netblue30@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
--- End Message ---