Package: graphviz
Version: 2.38.0-12ubuntu2
Severity: important

Dear Maintainer,

   The dot tool has had random crahses for dot files with multiple
   digraphs, sometimes leading to glib detected malloc / free
   corruption.

   I have tested this with the Address Sanitizer and Valgrind Memcheck,
   and found a simple memory leak (that I fixed), and a double free of
   the ranks (that I also fixed), and several lost memory allocations
   aka leaks, that I have not managed to fix, as they are somewhat
   secondary.

   This is an Ubuntu package, but I believe the issue to be still
   present in the Debian package.  Upstream bug tracking is tedious, so
   I am submitting here, instead.

   Thanks,
     Stephan

-- System Information:
Debian Release: stretch/sid
  APT prefers xenial-updates
  APT policy: (500, 'xenial-updates'), (500, 'xenial-security'), (500, 
'xenial'), (100, 'xenial-backports')
Architecture: amd64 (x86_64)
Foreign Architectures: i386

Kernel: Linux 4.4.0-47-generic (SMP w/2 CPU cores)
Locale: LANG=en_GB.UTF-8, LC_CTYPE=en_GB.UTF-8 (charmap=UTF-8)
Shell: /bin/sh linked to /bin/dash
Init: systemd (via /run/systemd/system)

Versions of packages graphviz depends on:
ii  libc6       2.23-0ubuntu4
ii  libcdt5     2.38.0-12ubuntu2
ii  libcgraph6  2.38.0-12ubuntu2
ii  libexpat1   2.1.0-7ubuntu0.16.04.2
ii  libgd3      2.1.1-4ubuntu0.16.04.5
ii  libgvc6     2.38.0-12ubuntu2
ii  libgvpr2    2.38.0-12ubuntu2
ii  libx11-6    2:1.6.3-1ubuntu2
ii  libxaw7     2:1.0.13-1
ii  libxmu6     2:1.1.2-2
ii  libxt6      1:1.1.5-0ubuntu1

Versions of packages graphviz recommends:
ii  fonts-liberation  1.07.4-1

Versions of packages graphviz suggests:
pn  graphviz-doc  <none>
ii  gsfonts       1:8.11+urwcyr1.0.7~pre44-4.2ubuntu1

-- no debconf information
--- graphviz.old/graphviz-2.38.0/lib/dotgen/dotinit.c	2014-04-13 21:40:25.000000000 +0100
+++ graphviz/graphviz-2.38.0/lib/dotgen/dotinit.c	2016-11-23 19:32:53.000000000 +0000
@@ -162,6 +162,8 @@
 
     free_list(GD_comp(g));
     if (GD_rank(g)) {
+	// SD: The deallocates here will also deallocate the .v field which
+	// aliases; and were causing double free errors
 	for (i = GD_minrank(g); i <= GD_maxrank(g); i++)
 	    free(GD_rank(g)[i].av);
 	if (GD_minrank(g) == -1)
--- graphviz.old/graphviz-2.38.0/lib/dotgen/flat.c	2014-04-13 21:40:25.000000000 +0100
+++ graphviz/graphviz-2.38.0/lib/dotgen/flat.c	2016-11-23 19:31:59.000000000 +0000
@@ -22,6 +22,11 @@
 
     v = GD_rank(g)[r].v =
 	ALLOC(GD_rank(g)[r].n + 2, GD_rank(g)[r].v, node_t *);
+
+    // Keep v and av in sync; ALLOC may move the previous allocation of .v and
+    // they are supposed to stay in sync
+    GD_rank(g)[r].av = GD_rank(g)[r].v;
+
     for (i = GD_rank(g)[r].n; i > pos; i--) {
 	v[i] = v[i - 1];
 	ND_order(v[i])++;
--- graphviz.old/graphviz-2.38.0/lib/dotgen/mincross.c	2014-04-13 21:40:25.000000000 +0100
+++ graphviz/graphviz-2.38.0/lib/dotgen/mincross.c	2016-11-23 19:33:41.000000000 +0000
@@ -1053,7 +1053,14 @@
     GD_rank(g) = N_NEW(GD_maxrank(g) + 2, rank_t);
     for (r = GD_minrank(g); r <= GD_maxrank(g); r++) {
 	GD_rank(g)[r].an = GD_rank(g)[r].n = cn[r];
+	// SD: Below allocation is unsafe, as these get deallocated differently
+	//
+	// node_t **v;		/* ordered list of nodes in rank    */
+	// node_t **av;		/* allocated list of nodes in rank  */
 	GD_rank(g)[r].av = GD_rank(g)[r].v = N_NEW(cn[r] + 1, node_t *);
+	// SD: Trying to have separate allocations does not work, below
+	//GD_rank(g)[r].av = N_NEW(cn[r] + 1, node_t *);
+	//GD_rank(g)[r].v  = N_NEW(cn[r] + 1, node_t *);
     }
     free(cn);
 }
--- graphviz.old/graphviz-2.38.0/lib/gvpr/mkdefs.c	2014-04-13 21:40:25.000000000 +0100
+++ graphviz/graphviz-2.38.0/lib/gvpr/mkdefs.c	2016-11-23 10:50:27.000000000 +0000
@@ -147,6 +147,7 @@
 	}
 	buf = malloc(BSIZE);
     }
+    free(buf);
 
     fp = fopen(filename, "w");
     if (!fp) {

Reply via email to