Blame SOURCES/libtiff-CVE-2016-9533_9534_9536_9537.patch

70f9f0
From 6c4480d2980dc61f3fcd4f43a499e69764133f1a Mon Sep 17 00:00:00 2001
70f9f0
From: =?UTF-8?q?Nikola=20Forr=C3=B3?= <nforro@redhat.com>
70f9f0
Date: Wed, 11 Jan 2017 12:50:33 +0100
70f9f0
Subject: [PATCH 1/5] Fix CVE-2016-9533, CVE-2016-9534, CVE-2016-9536,
70f9f0
 CVE-2016-9537
70f9f0
70f9f0
---
70f9f0
 libtiff/tif_pixarlog.c | 55 +++++++++++++++++++++-----------------------------
70f9f0
 libtiff/tif_write.c    |  7 +++++++
70f9f0
 tools/thumbnail.c      |  7 ++++++-
70f9f0
 tools/tiff2pdf.c       | 22 ++++++++++++++++++--
70f9f0
 tools/tiffcrop.c       | 31 ++++++++++++++++++++++++----
70f9f0
 5 files changed, 83 insertions(+), 39 deletions(-)
70f9f0
70f9f0
diff --git a/libtiff/tif_pixarlog.c b/libtiff/tif_pixarlog.c
70f9f0
index c961529..6128f2f 100644
70f9f0
--- a/libtiff/tif_pixarlog.c
70f9f0
+++ b/libtiff/tif_pixarlog.c
70f9f0
@@ -981,17 +981,14 @@ horizontalDifferenceF(float *ip, int n, int stride, uint16 *wp, uint16 *FromLT2)
70f9f0
 		a1 = (int32) CLAMP(ip[3]); wp[3] = (a1-a2) & mask; a2 = a1;
70f9f0
 	    }
70f9f0
 	} else {
70f9f0
-	    ip += n - 1;	/* point to last one */
70f9f0
-	    wp += n - 1;	/* point to last one */
70f9f0
-	    n -= stride;
70f9f0
-	    while (n > 0) {
70f9f0
-		REPEAT(stride, wp[0] = (uint16) CLAMP(ip[0]);
70f9f0
-				wp[stride] -= wp[0];
70f9f0
-				wp[stride] &= mask;
70f9f0
-				wp--; ip--)
70f9f0
-		n -= stride;
70f9f0
-	    }
70f9f0
-	    REPEAT(stride, wp[0] = (uint16) CLAMP(ip[0]); wp--; ip--)
70f9f0
+        REPEAT(stride, wp[0] = (uint16) CLAMP(ip[0]); wp++; ip++)
70f9f0
+        n -= stride;
70f9f0
+        while (n > 0) {
70f9f0
+            REPEAT(stride,
70f9f0
+                wp[0] = (uint16)(((int32)CLAMP(ip[0])-(int32)CLAMP(ip[-stride])) & mask);
70f9f0
+                wp++; ip++)
70f9f0
+            n -= stride;
70f9f0
+        }
70f9f0
 	}
70f9f0
     }
70f9f0
 }
70f9f0
@@ -1034,17 +1031,14 @@ horizontalDifference16(unsigned short *ip, int n, int stride,
70f9f0
 		a1 = CLAMP(ip[3]); wp[3] = (a1-a2) & mask; a2 = a1;
70f9f0
 	    }
70f9f0
 	} else {
70f9f0
-	    ip += n - 1;	/* point to last one */
70f9f0
-	    wp += n - 1;	/* point to last one */
70f9f0
+        REPEAT(stride, wp[0] = CLAMP(ip[0]); wp++; ip++)
70f9f0
 	    n -= stride;
70f9f0
 	    while (n > 0) {
70f9f0
-		REPEAT(stride, wp[0] = CLAMP(ip[0]);
70f9f0
-				wp[stride] -= wp[0];
70f9f0
-				wp[stride] &= mask;
70f9f0
-				wp--; ip--)
70f9f0
-		n -= stride;
70f9f0
-	    }
70f9f0
-	    REPEAT(stride, wp[0] = CLAMP(ip[0]); wp--; ip--)
70f9f0
+            REPEAT(stride,
70f9f0
+                wp[0] = (uint16)((CLAMP(ip[0])-CLAMP(ip[-stride])) & mask);
70f9f0
+                wp++; ip++)
70f9f0
+            n -= stride;
70f9f0
+        }
70f9f0
 	}
70f9f0
     }
70f9f0
 }
70f9f0
@@ -1087,18 +1081,15 @@ horizontalDifference8(unsigned char *ip, int n, int stride,
70f9f0
 		ip += 4;
70f9f0
 	    }
70f9f0
 	} else {
70f9f0
-	    wp += n + stride - 1;	/* point to last one */
70f9f0
-	    ip += n + stride - 1;	/* point to last one */
70f9f0
-	    n -= stride;
70f9f0
-	    while (n > 0) {
70f9f0
-		REPEAT(stride, wp[0] = CLAMP(ip[0]);
70f9f0
-				wp[stride] -= wp[0];
70f9f0
-				wp[stride] &= mask;
70f9f0
-				wp--; ip--)
70f9f0
-		n -= stride;
70f9f0
-	    }
70f9f0
-	    REPEAT(stride, wp[0] = CLAMP(ip[0]); wp--; ip--)
70f9f0
-	}
70f9f0
+        REPEAT(stride, wp[0] = CLAMP(ip[0]); wp++; ip++)
70f9f0
+        n -= stride;
70f9f0
+        while (n > 0) {
70f9f0
+            REPEAT(stride,
70f9f0
+                wp[0] = (uint16)((CLAMP(ip[0])-CLAMP(ip[-stride])) & mask);
70f9f0
+                wp++; ip++)
70f9f0
+            n -= stride;
70f9f0
+        }
70f9f0
+    }
70f9f0
     }
70f9f0
 }
70f9f0
 
70f9f0
diff --git a/libtiff/tif_write.c b/libtiff/tif_write.c
70f9f0
index 8792123..ce671af 100644
70f9f0
--- a/libtiff/tif_write.c
70f9f0
+++ b/libtiff/tif_write.c
70f9f0
@@ -742,7 +742,14 @@ TIFFFlushData1(TIFF* tif)
70f9f0
 		if (!TIFFAppendToStrip(tif,
70f9f0
 		    isTiled(tif) ? tif->tif_curtile : tif->tif_curstrip,
70f9f0
 		    tif->tif_rawdata, tif->tif_rawcc))
70f9f0
+        {
70f9f0
+            /* We update those variables even in case of error since there's */
70f9f0
+            /* code that doesn't really check the return code of this */
70f9f0
+            /* function */
70f9f0
+            tif->tif_rawcc = 0;
70f9f0
+            tif->tif_rawcp = tif->tif_rawdata;
70f9f0
 			return (0);
70f9f0
+        }
70f9f0
 		tif->tif_rawcc = 0;
70f9f0
 		tif->tif_rawcp = tif->tif_rawdata;
70f9f0
 	}
70f9f0
diff --git a/tools/thumbnail.c b/tools/thumbnail.c
70f9f0
index e14d290..9a9c439 100644
70f9f0
--- a/tools/thumbnail.c
70f9f0
+++ b/tools/thumbnail.c
70f9f0
@@ -587,12 +587,17 @@ generateThumbnail(TIFF* in, TIFF* out)
70f9f0
     rowsize = TIFFScanlineSize(in);
70f9f0
     rastersize = sh * rowsize;
70f9f0
     fprintf(stderr, "rastersize=%u\n", (unsigned int)rastersize);
70f9f0
-    raster = (unsigned char*)_TIFFmalloc(rastersize + 3);
70f9f0
+	/* +3 : add a few guard bytes since setrow() can read a bit */
70f9f0
+	/* outside buffer */
70f9f0
+    raster = (unsigned char*)_TIFFmalloc(rastersize+3);
70f9f0
     if (!raster) {
70f9f0
 	    TIFFError(TIFFFileName(in),
70f9f0
 		      "Can't allocate space for raster buffer.");
70f9f0
 	    return 0;
70f9f0
     }
70f9f0
+    raster[rastersize] = 0;
70f9f0
+    raster[rastersize+1] = 0;
70f9f0
+    raster[rastersize+2] = 0;
70f9f0
     rp = raster;
70f9f0
     for (s = 0; s < ns; s++) {
70f9f0
 	(void) TIFFReadEncodedStrip(in, s, rp, -1);
70f9f0
diff --git a/tools/tiff2pdf.c b/tools/tiff2pdf.c
70f9f0
index 2a64ec3..fbca305 100644
70f9f0
--- a/tools/tiff2pdf.c
70f9f0
+++ b/tools/tiff2pdf.c
70f9f0
@@ -285,7 +285,7 @@ tsize_t t2p_readwrite_pdf_image_tile(T2P*, TIFF*, TIFF*, ttile_t);
70f9f0
 int t2p_process_ojpeg_tables(T2P*, TIFF*);
70f9f0
 #endif
70f9f0
 #ifdef JPEG_SUPPORT
70f9f0
-int t2p_process_jpeg_strip(unsigned char*, tsize_t*, unsigned char*, tsize_t*, tstrip_t, uint32);
70f9f0
+int t2p_process_jpeg_strip(unsigned char*, tsize_t*, unsigned char*, tsize_t, tsize_t*, tstrip_t, uint32);
70f9f0
 #endif
70f9f0
 void t2p_tile_collapse_left(tdata_t, tsize_t, uint32, uint32, uint32);
70f9f0
 void t2p_write_advance_directory(T2P*, TIFF*);
70f9f0
@@ -2348,7 +2348,8 @@ tsize_t t2p_readwrite_pdf_image(T2P* t2p, TIFF* input, TIFF* output){
70f9f0
 				if(!t2p_process_jpeg_strip(
70f9f0
 					stripbuffer, 
70f9f0
 					&striplength, 
70f9f0
-					buffer, 
70f9f0
+					buffer,
70f9f0
+                    t2p->tiff_datasize,
70f9f0
 					&bufferoffset, 
70f9f0
 					i, 
70f9f0
 					t2p->tiff_length)){
70f9f0
@@ -3378,6 +3379,7 @@ int t2p_process_jpeg_strip(
70f9f0
 	unsigned char* strip, 
70f9f0
 	tsize_t* striplength, 
70f9f0
 	unsigned char* buffer, 
70f9f0
+    tsize_t buffersize,
70f9f0
 	tsize_t* bufferoffset, 
70f9f0
 	tstrip_t no, 
70f9f0
 	uint32 height){
70f9f0
@@ -3412,6 +3414,8 @@ int t2p_process_jpeg_strip(
70f9f0
 		}
70f9f0
 		switch( strip[i] ){
70f9f0
 			case 0xd8:	/* SOI - start of image */
70f9f0
+                if( *bufferoffset + 2 > buffersize )
70f9f0
+                    return(0);
70f9f0
 				_TIFFmemcpy(&(buffer[*bufferoffset]), &(strip[i-1]), 2);
70f9f0
 				*bufferoffset+=2;
70f9f0
 				break;
70f9f0
@@ -3421,12 +3425,18 @@ int t2p_process_jpeg_strip(
70f9f0
 			case 0xc9:	/* SOF9 */
70f9f0
 			case 0xca:	/* SOF10 */
70f9f0
 				if(no==0){
70f9f0
+                    if( *bufferoffset + datalen + 2 + 6 > buffersize )
70f9f0
+                        return(0);
70f9f0
 					_TIFFmemcpy(&(buffer[*bufferoffset]), &(strip[i-1]), datalen+2);
70f9f0
+                    if( *bufferoffset + 9 >= buffersize )
70f9f0
+                        return(0);
70f9f0
 					ncomp = buffer[*bufferoffset+9];
70f9f0
 					if (ncomp < 1 || ncomp > 4)
70f9f0
 						return(0);
70f9f0
 					v_samp=1;
70f9f0
 					h_samp=1;
70f9f0
+                    if( *bufferoffset + 11 + 3*(ncomp-1) >= buffersize )
70f9f0
+                        return(0);
70f9f0
 					for(j=0;j
70f9f0
 						uint16 samp = buffer[*bufferoffset+11+(3*j)];
70f9f0
 						if( (samp>>4) > h_samp) 
70f9f0
@@ -3458,20 +3468,28 @@ int t2p_process_jpeg_strip(
70f9f0
 				break;
70f9f0
 			case 0xc4: /* DHT */
70f9f0
 			case 0xdb: /* DQT */
70f9f0
+                if( *bufferoffset + datalen + 2 > buffersize )
70f9f0
+                    return(0);
70f9f0
 				_TIFFmemcpy(&(buffer[*bufferoffset]), &(strip[i-1]), datalen+2);
70f9f0
 				*bufferoffset+=datalen+2;
70f9f0
 				break;
70f9f0
 			case 0xda: /* SOS */
70f9f0
 				if(no==0){
70f9f0
+                    if( *bufferoffset + datalen + 2 > buffersize )
70f9f0
+                        return(0);
70f9f0
 					_TIFFmemcpy(&(buffer[*bufferoffset]), &(strip[i-1]), datalen+2);
70f9f0
 					*bufferoffset+=datalen+2;
70f9f0
 				} else {
70f9f0
+                    if( *bufferoffset + 2 > buffersize )
70f9f0
+                        return(0);
70f9f0
 					buffer[(*bufferoffset)++]=0xff;
70f9f0
 					buffer[(*bufferoffset)++]=
70f9f0
                                             (unsigned char)(0xd0 | ((no-1)%8));
70f9f0
 				}
70f9f0
 				i += datalen + 1;
70f9f0
 				/* copy remainder of strip */
70f9f0
+                if( *bufferoffset + *striplength - i > buffersize )
70f9f0
+                    return(0);
70f9f0
 				_TIFFmemcpy(&(buffer[*bufferoffset]), &(strip[i]), *striplength - i);
70f9f0
 				*bufferoffset+= *striplength - i;
70f9f0
 				return(1);
70f9f0
diff --git a/tools/tiffcrop.c b/tools/tiffcrop.c
70f9f0
index f04e2eb..02c53cd 100644
70f9f0
--- a/tools/tiffcrop.c
70f9f0
+++ b/tools/tiffcrop.c
70f9f0
@@ -5744,7 +5744,8 @@ loadImage(TIFF* in, struct image_data *image, struct dump_opts *dump, unsigned c
70f9f0
   {
70f9f0
   uint32   i;
70f9f0
   float    xres = 0.0, yres = 0.0;
70f9f0
-  uint16   nstrips = 0, ntiles = 0, planar = 0;
70f9f0
+  uint32   nstrips = 0, ntiles = 0;
70f9f0
+  uint16   planar = 0;
70f9f0
   uint16   bps = 0, spp = 0, res_unit = 0;
70f9f0
   uint16   orientation = 0;
70f9f0
   uint16   input_compression = 0, input_photometric = 0;
70f9f0
@@ -6049,17 +6050,31 @@ loadImage(TIFF* in, struct image_data *image, struct dump_opts *dump, unsigned c
70f9f0
     }
70f9f0
  
70f9f0
   read_buff = *read_ptr;
70f9f0
+  /* +3 : add a few guard bytes since reverseSamples16bits() can read a bit */
70f9f0
+  /* outside buffer */
70f9f0
   if (!read_buff)
70f9f0
-    read_buff = (unsigned char *)_TIFFmalloc(buffsize);
70f9f0
+  {
70f9f0
+    if( buffsize > 0xFFFFFFFFU - 3 )
70f9f0
+    {
70f9f0
+        TIFFError("loadImage", "Unable to allocate/reallocate read buffer");
70f9f0
+        return (-1);
70f9f0
+    }
70f9f0
+    read_buff = (unsigned char *)_TIFFmalloc(buffsize+3);
70f9f0
+  }
70f9f0
   else
70f9f0
     {
70f9f0
     if (prev_readsize < buffsize)
70f9f0
+    {
70f9f0
+      if( buffsize > 0xFFFFFFFFU - 3 )
70f9f0
       {
70f9f0
-      new_buff = _TIFFrealloc(read_buff, buffsize);
70f9f0
+          TIFFError("loadImage", "Unable to allocate/reallocate read buffer");
70f9f0
+          return (-1);
70f9f0
+      }
70f9f0
+      new_buff = _TIFFrealloc(read_buff, buffsize+3);
70f9f0
       if (!new_buff)
70f9f0
         {
70f9f0
 	free (read_buff);
70f9f0
-        read_buff = (unsigned char *)_TIFFmalloc(buffsize);
70f9f0
+        read_buff = (unsigned char *)_TIFFmalloc(buffsize+3);
70f9f0
         }
70f9f0
       else
70f9f0
         read_buff = new_buff;
70f9f0
@@ -6071,6 +6086,9 @@ loadImage(TIFF* in, struct image_data *image, struct dump_opts *dump, unsigned c
70f9f0
     TIFFError("loadImage", "Unable to allocate/reallocate read buffer");
70f9f0
     return (-1);
70f9f0
     }
70f9f0
+  read_buff[buffsize] = 0;
70f9f0
+  read_buff[buffsize+1] = 0;
70f9f0
+  read_buff[buffsize+2] = 0;
70f9f0
 
70f9f0
   prev_readsize = buffsize;
70f9f0
   *read_ptr = read_buff;
70f9f0
@@ -8877,6 +8895,11 @@ reverseSamplesBytes (uint16 spp, uint16 bps, uint32 width,
70f9f0
     }
70f9f0
 
70f9f0
   bytes_per_pixel  = ((bps * spp) + 7) / 8;
70f9f0
+  if( bytes_per_pixel > sizeof(swapbuff) )
70f9f0
+  {
70f9f0
+    TIFFError("reverseSamplesBytes","bytes_per_pixel too large");
70f9f0
+    return (1);
70f9f0
+  }
70f9f0
   switch (bps / 8)
70f9f0
      {
70f9f0
      case 8:  /* Use memcpy for multiple bytes per sample data */
70f9f0
-- 
70f9f0
2.7.4
70f9f0