From 06f37dd08f8367c043a28be1d8d1020af33bd18a Mon Sep 17 00:00:00 2001
From: Cristy <urban-warrior@imagemagick.org>
Date: Thu, 1 Dec 2016 20:05:59 -0500
Subject: [PATCH] Fix possible buffer overflow when writing compressed TIFFS

This a partial fix for CVE-2016-8707

bug-debian: https://bugs.debian.org/848139
bug: http://www.talosintelligence.com/reports/TALOS-2016-0216/
origin: https://github.com/ImageMagick/ImageMagick/commit/fde5f55af94f189f16958535a9c22b439d71ac93
---
 coders/tiff.c | 33 +++++++++++++++++++--------------
 1 file changed, 19 insertions(+), 14 deletions(-)

diff --git a/coders/tiff.c b/coders/tiff.c
index fcd902858..f4a5286ba 100644
--- a/coders/tiff.c
+++ b/coders/tiff.c
@@ -979,7 +979,7 @@ static Image *ReadTIFFImage(const ImageInfo *image_info,
     width;
 
   unsigned char
-    *pixels;
+    *tiff_pixels;
 
   /*
     Open image.
@@ -1381,7 +1381,13 @@ RestoreMSCWarning
       method=ReadTileMethod;
     quantum_info->endian=LSBEndian;
     quantum_type=RGBQuantum;
-    pixels=GetQuantumPixels(quantum_info);
+    tiff_pixels=(unsigned char *) AcquireMagickMemory(TIFFScanlineSize(tiff)+
+      sizeof(uint32));
+    if (tiff_pixels == (unsigned char *) NULL)
+      {
+        TIFFClose(tiff);
+        ThrowReaderException(ResourceLimitError,"MemoryAllocationFailed");
+      }
     switch (method)
     {
       case ReadSingleSampleMethod:
@@ -1464,7 +1470,6 @@ RestoreMSCWarning
             TIFFClose(tiff);
             ThrowReaderException(ResourceLimitError,"MemoryAllocationFailed");
           }
-        pixels=GetQuantumPixels(quantum_info);
         for (y=0; y < (ssize_t) image->rows; y++)
         {
           int
@@ -1473,14 +1478,14 @@ RestoreMSCWarning
           register PixelPacket
             *restrict q;
 
-          status=TIFFReadPixels(tiff,bits_per_sample,0,y,(char *) pixels);
+          status=TIFFReadPixels(tiff,bits_per_sample,0,y,(char *) tiff_pixels);
           if (status == -1)
             break;
           q=QueueAuthenticPixels(image,0,y,image->columns,1,exception);
           if (q == (PixelPacket *) NULL)
             break;
           length=ImportQuantumPixels(image,(CacheView *) NULL,quantum_info,
-            quantum_type,pixels,exception);
+            quantum_type,tiff_pixels,exception);
           (void) length;
           if (SyncAuthenticPixels(image,exception) == MagickFalse)
             break;
@@ -1522,7 +1527,6 @@ RestoreMSCWarning
             TIFFClose(tiff);
             ThrowReaderException(ResourceLimitError,"MemoryAllocationFailed");
           }
-        pixels=GetQuantumPixels(quantum_info);
         for (y=0; y < (ssize_t) image->rows; y++)
         {
           int
@@ -1531,14 +1535,14 @@ RestoreMSCWarning
           register PixelPacket
             *restrict q;
 
-          status=TIFFReadPixels(tiff,bits_per_sample,0,y,(char *) pixels);
+          status=TIFFReadPixels(tiff,bits_per_sample,0,y,(char *) tiff_pixels);
           if (status == -1)
             break;
           q=QueueAuthenticPixels(image,0,y,image->columns,1,exception);
           if (q == (PixelPacket *) NULL)
             break;
           length=ImportQuantumPixels(image,(CacheView *) NULL,quantum_info,
-            quantum_type,pixels,exception);
+            quantum_type,tiff_pixels,exception);
           if (SyncAuthenticPixels(image,exception) == MagickFalse)
             break;
           if (image->previous == (Image *) NULL)
@@ -1567,7 +1571,7 @@ RestoreMSCWarning
               status;
 
             status=TIFFReadPixels(tiff,bits_per_sample,(tsample_t) i,y,(char *)
-              pixels);
+              tiff_pixels);
             if (status == -1)
               break;
             q=GetAuthenticPixels(image,0,y,image->columns,1,exception);
@@ -1593,7 +1597,7 @@ RestoreMSCWarning
                 default: quantum_type=UndefinedQuantum; break;
               }
             length=ImportQuantumPixels(image,(CacheView *) NULL,quantum_info,
-              quantum_type,pixels,exception);
+              quantum_type,tiff_pixels,exception);
             if (SyncAuthenticPixels(image,exception) == MagickFalse)
               break;
           }
@@ -1630,13 +1634,13 @@ RestoreMSCWarning
             break;
           if (i == 0)
             {
-              if (TIFFReadRGBAStrip(tiff,(tstrip_t) y,(uint32 *) pixels) == 0)
+              if (TIFFReadRGBAStrip(tiff,(tstrip_t) y,(uint32 *) tiff_pixels) == 0)
                 break;
               i=(ssize_t) MagickMin((ssize_t) rows_per_strip,(ssize_t)
                 image->rows-y);
             }
           i--;
-          p=((uint32 *) pixels)+image->columns*i;
+          p=((uint32 *) tiff_pixels)+image->columns*i;
           for (x=0; x < (ssize_t) image->columns; x++)
           {
             SetPixelRed(q,ScaleCharToQuantum((unsigned char)
@@ -1689,8 +1693,8 @@ RestoreMSCWarning
             TIFFClose(tiff);
             ThrowReaderException(ResourceLimitError,"MemoryAllocationFailed");
           }
-        tile_pixels=(uint32 *) AcquireQuantumMemory(columns,
-          rows*sizeof(*tile_pixels));
+        tile_pixels=(uint32 *) AcquireQuantumMemory(columns,rows*
+           sizeof(*tile_pixels));
         if (tile_pixels == (uint32 *) NULL)
           {
             TIFFClose(tiff);
@@ -1847,6 +1851,7 @@ RestoreMSCWarning
         break;
       }
     }
+    tiff_pixels=(unsigned char *) RelinquishMagickMemory(tiff_pixels);
     SetQuantumImageType(image,quantum_type);
   next_tiff_frame:
     if (quantum_info != (QuantumInfo *) NULL)
