~ruther/guix-local

ed5940b6172bbdf5b4787183b19623219f6c7347 — Leo Famulari 9 years ago 9c85fea
gnu: libtiff: Fix CVE-2016-{3623,3945,3990,3991,5321,5323}.

* gnu/packages/image.scm (libtiff)[replacement]: New field.
(libtiff/fixed): New variable.
* gnu/packages/patches/libtiff-CVE-2016-3623.patch,
gnu/packages/patches/libtiff-CVE-2016-3945.patch,
gnu/packages/patches/libtiff-CVE-2016-3990.patch,
gnu/packages/patches/libtiff-CVE-2016-3991.patch,
gnu/packages/patches/libtiff-CVE-2016-5321.patch,
gnu/packages/patches/libtiff-CVE-2016-5323.patch: New files.
* gnu/local.mk (dist_patch_DATA): Add them.
M gnu/local.mk => gnu/local.mk +6 -0
@@ 626,6 626,12 @@ dist_patch_DATA =						\
  %D%/packages/patches/libtar-CVE-2013-4420.patch \
  %D%/packages/patches/libtheora-config-guess.patch		\
  %D%/packages/patches/libtiff-CVE-2015-8665+CVE-2015-8683.patch \
  %D%/packages/patches/libtiff-CVE-2016-3623.patch		\
  %D%/packages/patches/libtiff-CVE-2016-3945.patch		\
  %D%/packages/patches/libtiff-CVE-2016-3990.patch		\
  %D%/packages/patches/libtiff-CVE-2016-3991.patch		\
  %D%/packages/patches/libtiff-CVE-2016-5321.patch		\
  %D%/packages/patches/libtiff-CVE-2016-5323.patch		\
  %D%/packages/patches/libtiff-oob-accesses-in-decode.patch	\
  %D%/packages/patches/libtiff-oob-write-in-nextdecode.patch	\
  %D%/packages/patches/libtool-skip-tests2.patch		\

M gnu/packages/image.scm => gnu/packages/image.scm +17 -0
@@ 150,6 150,7 @@ maximum quality factor.")
(define-public libtiff
  (package
   (name "libtiff")
   (replacement libtiff/fixed)
   (version "4.0.6")
   (source (origin
            (method url-fetch)


@@ 182,6 183,22 @@ collection of tools for doing simple manipulations of TIFF images.")
                                  "See COPYRIGHT in the distribution."))
   (home-page "http://www.remotesensing.org/libtiff/")))

(define libtiff/fixed
  (package
    (inherit libtiff)
    (source (origin
              (inherit (package-source libtiff))
              (patches (search-patches
                         "libtiff-oob-accesses-in-decode.patch"
                         "libtiff-oob-write-in-nextdecode.patch"
                         "libtiff-CVE-2015-8665+CVE-2015-8683.patch"
                         "libtiff-CVE-2016-3623.patch"
                         "libtiff-CVE-2016-3945.patch"
                         "libtiff-CVE-2016-3990.patch"
                         "libtiff-CVE-2016-3991.patch"
                         "libtiff-CVE-2016-5321.patch"
                         "libtiff-CVE-2016-5323.patch"))))))

(define-public libwmf
  (package
    (name "libwmf")

A gnu/packages/patches/libtiff-CVE-2016-3623.patch => gnu/packages/patches/libtiff-CVE-2016-3623.patch +30 -0
@@ 0,0 1,30 @@
Fix CVE-2016-3623.

https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2016-3623
http://bugzilla.maptools.org/show_bug.cgi?id=2569

Patch extracted from upstream CVS repo with:
$ cvs diff -u -r1.16 -r1.17 tools/rgb2ycbcr.c

Index: tools/rgb2ycbcr.c
===================================================================
RCS file: /cvs/maptools/cvsroot/libtiff/tools/rgb2ycbcr.c,v
retrieving revision 1.16
retrieving revision 1.17
diff -u -r1.16 -r1.17
--- libtiff/tools/rgb2ycbcr.c	21 Jun 2015 01:09:10 -0000	1.16
+++ libtiff/tools/rgb2ycbcr.c	15 Aug 2016 21:26:56 -0000	1.17
@@ -95,9 +95,13 @@
 			break;
 		case 'h':
 			horizSubSampling = atoi(optarg);
+            if( horizSubSampling != 1 && horizSubSampling != 2 && horizSubSampling != 4 )
+                usage(-1);
 			break;
 		case 'v':
 			vertSubSampling = atoi(optarg);
+            if( vertSubSampling != 1 && vertSubSampling != 2 && vertSubSampling != 4 )
+                usage(-1);
 			break;
 		case 'r':
 			rowsperstrip = atoi(optarg);

A gnu/packages/patches/libtiff-CVE-2016-3945.patch => gnu/packages/patches/libtiff-CVE-2016-3945.patch +94 -0
@@ 0,0 1,94 @@
Fix CVE-2016-3945 (integer overflow in size of allocated
buffer, when -b mode is enabled, that could result in out-of-bounds
write).

https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2016-3945
http://bugzilla.maptools.org/show_bug.cgi?id=2545

Patch extracted from upstream CVS repo with:
$ cvs diff -u -r1.21 -r1.22 tools/tiff2rgba.c

Index: tools/tiff2rgba.c
===================================================================
RCS file: /cvs/maptools/cvsroot/libtiff/tools/tiff2rgba.c,v
retrieving revision 1.21
retrieving revision 1.22
diff -u -r1.21 -r1.22
--- libtiff/tools/tiff2rgba.c	21 Jun 2015 01:09:10 -0000	1.21
+++ libtiff/tools/tiff2rgba.c	15 Aug 2016 20:06:41 -0000	1.22
@@ -147,6 +147,7 @@
     uint32  row, col;
     uint32  *wrk_line;
     int	    ok = 1;
+    uint32  rastersize, wrk_linesize;
 
     TIFFGetField(in, TIFFTAG_IMAGEWIDTH, &width);
     TIFFGetField(in, TIFFTAG_IMAGELENGTH, &height);
@@ -163,7 +164,13 @@
     /*
      * Allocate tile buffer
      */
-    raster = (uint32*)_TIFFmalloc(tile_width * tile_height * sizeof (uint32));
+    rastersize = tile_width * tile_height * sizeof (uint32);
+    if (tile_width != (rastersize / tile_height) / sizeof( uint32))
+    {
+	TIFFError(TIFFFileName(in), "Integer overflow when calculating raster buffer");
+	exit(-1);
+    }
+    raster = (uint32*)_TIFFmalloc(rastersize);
     if (raster == 0) {
         TIFFError(TIFFFileName(in), "No space for raster buffer");
         return (0);
@@ -173,7 +180,13 @@
      * Allocate a scanline buffer for swapping during the vertical
      * mirroring pass.
      */
-    wrk_line = (uint32*)_TIFFmalloc(tile_width * sizeof (uint32));
+    wrk_linesize = tile_width * sizeof (uint32);
+    if (tile_width != wrk_linesize / sizeof (uint32))
+    {
+        TIFFError(TIFFFileName(in), "Integer overflow when calculating wrk_line buffer");
+	exit(-1);
+    }
+    wrk_line = (uint32*)_TIFFmalloc(wrk_linesize);
     if (!wrk_line) {
         TIFFError(TIFFFileName(in), "No space for raster scanline buffer");
         ok = 0;
@@ -249,6 +262,7 @@
     uint32  row;
     uint32  *wrk_line;
     int	    ok = 1;
+    uint32  rastersize, wrk_linesize;
 
     TIFFGetField(in, TIFFTAG_IMAGEWIDTH, &width);
     TIFFGetField(in, TIFFTAG_IMAGELENGTH, &height);
@@ -263,7 +277,13 @@
     /*
      * Allocate strip buffer
      */
-    raster = (uint32*)_TIFFmalloc(width * rowsperstrip * sizeof (uint32));
+    rastersize = width * rowsperstrip * sizeof (uint32);
+    if (width != (rastersize / rowsperstrip) / sizeof( uint32))
+    {
+	TIFFError(TIFFFileName(in), "Integer overflow when calculating raster buffer");
+	exit(-1);
+    }
+    raster = (uint32*)_TIFFmalloc(rastersize);
     if (raster == 0) {
         TIFFError(TIFFFileName(in), "No space for raster buffer");
         return (0);
@@ -273,7 +293,13 @@
      * Allocate a scanline buffer for swapping during the vertical
      * mirroring pass.
      */
-    wrk_line = (uint32*)_TIFFmalloc(width * sizeof (uint32));
+    wrk_linesize = width * sizeof (uint32);
+    if (width != wrk_linesize / sizeof (uint32))
+    {
+        TIFFError(TIFFFileName(in), "Integer overflow when calculating wrk_line buffer");
+	exit(-1);
+    }
+    wrk_line = (uint32*)_TIFFmalloc(wrk_linesize);
     if (!wrk_line) {
         TIFFError(TIFFFileName(in), "No space for raster scanline buffer");
         ok = 0;

A gnu/packages/patches/libtiff-CVE-2016-3990.patch => gnu/packages/patches/libtiff-CVE-2016-3990.patch +31 -0
@@ 0,0 1,31 @@
Fix CVE-2016-3990 (write buffer overflow in PixarLogEncode if more input
samples are provided than expected by PixarLogSetupEncode).

https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2016-3990
http://bugzilla.maptools.org/show_bug.cgi?id=2544

Patch extracted from upstream CVS repo with:
$ cvs diff -u -r1.45 -r1.46 libtiff/tif_pixarlog.c

Index: libtiff/tif_pixarlog.c
===================================================================
RCS file: /cvs/maptools/cvsroot/libtiff/libtiff/tif_pixarlog.c,v
retrieving revision 1.45
retrieving revision 1.46
diff -u -r1.45 -r1.46
--- libtiff/libtiff/tif_pixarlog.c	28 Jun 2016 15:37:33 -0000	1.45
+++ libtiff/libtiff/tif_pixarlog.c	15 Aug 2016 20:49:48 -0000	1.46
@@ -1141,6 +1141,13 @@
 	}
 
 	llen = sp->stride * td->td_imagewidth;
+    /* Check against the number of elements (of size uint16) of sp->tbuf */
+    if( n > td->td_rowsperstrip * llen )
+    {
+        TIFFErrorExt(tif->tif_clientdata, module,
+                     "Too many input bytes provided");
+        return 0;
+    }
 
 	for (i = 0, up = sp->tbuf; i < n; i += llen, up += llen) {
 		switch (sp->user_datafmt)  {

A gnu/packages/patches/libtiff-CVE-2016-3991.patch => gnu/packages/patches/libtiff-CVE-2016-3991.patch +123 -0
@@ 0,0 1,123 @@
Fix CVE-2016-3991 (out-of-bounds write in loadImage()).

https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2016-3991
http://bugzilla.maptools.org/show_bug.cgi?id=2543

Patch extracted from upstream CVS repo with:
$ cvs diff -u -r1.37 -r1.38 tools/tiffcrop.c

Index: tools/tiffcrop.c
===================================================================
RCS file: /cvs/maptools/cvsroot/libtiff/tools/tiffcrop.c,v
retrieving revision 1.37
retrieving revision 1.38
diff -u -r1.37 -r1.38
--- libtiff/tools/tiffcrop.c	11 Jul 2016 21:38:31 -0000	1.37
+++ libtiff/tools/tiffcrop.c	15 Aug 2016 21:05:40 -0000	1.38
@@ -798,6 +798,11 @@
     }
 
   tile_buffsize = tilesize;
+  if (tilesize == 0 || tile_rowsize == 0)
+  {
+     TIFFError("readContigTilesIntoBuffer", "Tile size or tile rowsize is zero");
+     exit(-1);
+  }
 
   if (tilesize < (tsize_t)(tl * tile_rowsize))
     {
@@ -807,7 +812,12 @@
               tilesize, tl * tile_rowsize);
 #endif
     tile_buffsize = tl * tile_rowsize;
-    } 
+    if (tl != (tile_buffsize / tile_rowsize))
+    {
+    	TIFFError("readContigTilesIntoBuffer", "Integer overflow when calculating buffer size.");
+        exit(-1);
+    }
+    }
 
   tilebuf = _TIFFmalloc(tile_buffsize);
   if (tilebuf == 0)
@@ -1210,6 +1220,12 @@
       !TIFFGetField(out, TIFFTAG_BITSPERSAMPLE, &bps) )
       return 1;
 
+  if (tilesize == 0 || tile_rowsize == 0 || tl == 0 || tw == 0)
+  {
+    TIFFError("writeBufferToContigTiles", "Tile size, tile row size, tile width, or tile length is zero");
+    exit(-1);
+  }
+  
   tile_buffsize = tilesize;
   if (tilesize < (tsize_t)(tl * tile_rowsize))
     {
@@ -1219,6 +1235,11 @@
               tilesize, tl * tile_rowsize);
 #endif
     tile_buffsize = tl * tile_rowsize;
+    if (tl != tile_buffsize / tile_rowsize)
+    {
+	TIFFError("writeBufferToContigTiles", "Integer overflow when calculating buffer size");
+	exit(-1);
+    }
     }
 
   tilebuf = _TIFFmalloc(tile_buffsize);
@@ -5945,12 +5966,27 @@
     TIFFGetField(in, TIFFTAG_TILELENGTH, &tl);
 
     tile_rowsize  = TIFFTileRowSize(in);      
+    if (ntiles == 0 || tlsize == 0 || tile_rowsize == 0)
+    {
+	TIFFError("loadImage", "File appears to be tiled, but the number of tiles, tile size, or tile rowsize is zero.");
+	exit(-1);
+    }
     buffsize = tlsize * ntiles;
+    if (tlsize != (buffsize / ntiles))
+    {
+	TIFFError("loadImage", "Integer overflow when calculating buffer size");
+	exit(-1);
+    }
 
-        
     if (buffsize < (uint32)(ntiles * tl * tile_rowsize))
       {
       buffsize = ntiles * tl * tile_rowsize;
+      if (ntiles != (buffsize / tl / tile_rowsize))
+      {
+	TIFFError("loadImage", "Integer overflow when calculating buffer size");
+	exit(-1);
+      }
+      
 #ifdef DEBUG2
       TIFFError("loadImage",
 	        "Tilesize %u is too small, using ntiles * tilelength * tilerowsize %lu",
@@ -5969,8 +6005,25 @@
     TIFFGetFieldDefaulted(in, TIFFTAG_ROWSPERSTRIP, &rowsperstrip);
     stsize = TIFFStripSize(in);
     nstrips = TIFFNumberOfStrips(in);
+    if (nstrips == 0 || stsize == 0)
+    {
+	TIFFError("loadImage", "File appears to be striped, but the number of stipes or stripe size is zero.");
+	exit(-1);
+    }
+
     buffsize = stsize * nstrips;
-    
+    if (stsize != (buffsize / nstrips))
+    {
+	TIFFError("loadImage", "Integer overflow when calculating buffer size");
+	exit(-1);
+    }
+    uint32 buffsize_check;
+    buffsize_check = ((length * width * spp * bps) + 7);
+    if (length != ((buffsize_check - 7) / width / spp / bps))
+    {
+	TIFFError("loadImage", "Integer overflow detected.");
+	exit(-1);
+    }
     if (buffsize < (uint32) (((length * width * spp * bps) + 7) / 8))
       {
       buffsize =  ((length * width * spp * bps) + 7) / 8;

A gnu/packages/patches/libtiff-CVE-2016-5321.patch => gnu/packages/patches/libtiff-CVE-2016-5321.patch +25 -0
@@ 0,0 1,25 @@
Fix CVE-2016-5321. 

https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2016-5321
http://bugzilla.maptools.org/show_bug.cgi?id=2558

Patch extracted from upstream CVS repo with:
$ cvs diff -u -r1.35 -r1.36 tools/tiffcrop.c

Index: tools/tiffcrop.c
===================================================================
RCS file: /cvs/maptools/cvsroot/libtiff/tools/tiffcrop.c,v
retrieving revision 1.35
retrieving revision 1.36
diff -u -r1.35 -r1.36
--- libtiff/tools/tiffcrop.c	19 Aug 2015 02:31:04 -0000	1.35
+++ libtiff/tools/tiffcrop.c	11 Jul 2016 21:26:03 -0000	1.36
@@ -989,7 +989,7 @@
     nrow = (row + tl > imagelength) ? imagelength - row : tl;
     for (col = 0; col < imagewidth; col += tw)
       {
-      for (s = 0; s < spp; s++)
+      for (s = 0; s < spp && s < MAX_SAMPLES; s++)
         {  /* Read each plane of a tile set into srcbuffs[s] */
 	tbytes = TIFFReadTile(in, srcbuffs[s], col, row, 0, s);
         if (tbytes < 0  && !ignore)

A gnu/packages/patches/libtiff-CVE-2016-5323.patch => gnu/packages/patches/libtiff-CVE-2016-5323.patch +88 -0
@@ 0,0 1,88 @@
Fix CVE-2016-5323.

https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2016-5323
http://bugzilla.maptools.org/show_bug.cgi?id=2559

Patch extracted from upstream CVS repo with:
$ cvs diff -u -r1.36  -r1.37 tools/tiffcrop.c

Index: tools/tiffcrop.c
===================================================================
RCS file: /cvs/maptools/cvsroot/libtiff/tools/tiffcrop.c,v
retrieving revision 1.36
retrieving revision 1.37
diff -u -r1.36 -r1.37
--- libtiff/tools/tiffcrop.c	11 Jul 2016 21:26:03 -0000	1.36
+++ libtiff/tools/tiffcrop.c	11 Jul 2016 21:38:31 -0000	1.37
@@ -3738,7 +3738,7 @@
 
       matchbits = maskbits << (8 - src_bit - bps); 
       /* load up next sample from each plane */
-      for (s = 0; s < spp; s++)
+      for (s = 0; (s < spp) && (s < MAX_SAMPLES); s++)
         {
 	src = in[s] + src_offset + src_byte;
         buff1 = ((*src) & matchbits) << (src_bit);
@@ -3837,7 +3837,7 @@
       src_bit  = bit_offset % 8;
 
       matchbits = maskbits << (16 - src_bit - bps); 
-      for (s = 0; s < spp; s++)
+      for (s = 0; (s < spp) && (s < MAX_SAMPLES); s++)
         {
 	src = in[s] + src_offset + src_byte;
         if (little_endian)
@@ -3947,7 +3947,7 @@
       src_bit  = bit_offset % 8;
 
       matchbits = maskbits << (32 - src_bit - bps); 
-      for (s = 0; s < spp; s++)
+      for (s = 0; (s < spp) && (s < MAX_SAMPLES); s++)
         {
 	src = in[s] + src_offset + src_byte;
         if (little_endian)
@@ -4073,7 +4073,7 @@
       src_bit  = bit_offset % 8;
 
       matchbits = maskbits << (64 - src_bit - bps); 
-      for (s = 0; s < spp; s++)
+      for (s = 0; (s < spp) && (s < MAX_SAMPLES); s++)
 	{
 	src = in[s] + src_offset + src_byte;
 	if (little_endian)
@@ -4263,7 +4263,7 @@
 
       matchbits = maskbits << (8 - src_bit - bps); 
       /* load up next sample from each plane */
-      for (s = 0; s < spp; s++)
+      for (s = 0; (s < spp) && (s < MAX_SAMPLES); s++)
         {
 	src = in[s] + src_offset + src_byte;
         buff1 = ((*src) & matchbits) << (src_bit);
@@ -4362,7 +4362,7 @@
       src_bit  = bit_offset % 8;
 
       matchbits = maskbits << (16 - src_bit - bps); 
-      for (s = 0; s < spp; s++)
+      for (s = 0; (s < spp) && (s < MAX_SAMPLES); s++)
         {
 	src = in[s] + src_offset + src_byte;
         if (little_endian)
@@ -4471,7 +4471,7 @@
       src_bit  = bit_offset % 8;
 
       matchbits = maskbits << (32 - src_bit - bps); 
-      for (s = 0; s < spp; s++)
+      for (s = 0; (s < spp) && (s < MAX_SAMPLES); s++)
         {
 	src = in[s] + src_offset + src_byte;
         if (little_endian)
@@ -4597,7 +4597,7 @@
       src_bit  = bit_offset % 8;
 
       matchbits = maskbits << (64 - src_bit - bps); 
-      for (s = 0; s < spp; s++)
+      for (s = 0; (s < spp) && (s < MAX_SAMPLES); s++)
 	{
 	src = in[s] + src_offset + src_byte;
 	if (little_endian)