From 9650b08507b883f76258f5a8bac886ada65dd622 Mon Sep 17 00:00:00 2001
From: dirk <dirk@aa41f4f7-0bf4-0310-aa73-e5a19afd5a74>
Date: Thu, 23 Oct 2014 21:54:08 +0000
Subject: [PATCH] Fixed buffer overflow in PCX reader.

Fix a buffer overflow in pcx reader by checking the pcx file.
This problem was discovered by fuzzing some pcx file.

This is fix for the pcx format for TEMP-0000000-77B6EF aka CVE-2014-8355

git-svn-id: https://subversion.imagemagick.org/subversion/ImageMagick/branches/ImageMagick-6@16774 aa41f4f7-0bf4-0310-aa73-e5a19afd5a74
forwarded: yes
Bug-debian: http://bugs.debian.org/767240
Applied-Upstream: 6.8.9.9
---
 coders/pcx.c | 28 +++++++++++++++-------------
 1 file changed, 15 insertions(+), 13 deletions(-)

diff --git a/coders/pcx.c b/coders/pcx.c
index 88a26bb..75c4c54 100644
--- a/coders/pcx.c
+++ b/coders/pcx.c
@@ -219,6 +219,13 @@ static inline size_t MagickMin(const size_t x,const size_t y)
 
 static Image *ReadPCXImage(const ImageInfo *image_info,ExceptionInfo *exception)
 {
+#define ThrowPCXException(severity,tag) \
+  { \
+    scanline=(unsigned char *) RelinquishMagickMemory(scanline); \
+    pcx_pixels=(unsigned char *) RelinquishMagickMemory(pcx_pixels); \
+    ThrowReaderException(severity,tag); \
+  }
+
   Image
     *image;
 
@@ -261,7 +268,7 @@ static Image *ReadPCXImage(const ImageInfo *image_info,ExceptionInfo *exception)
 
   unsigned char
     packet,
-    *pcx_colormap,
+    pcx_colormap[768],
     *pcx_pixels,
     *scanline;
 
@@ -317,7 +324,6 @@ static Image *ReadPCXImage(const ImageInfo *image_info,ExceptionInfo *exception)
       if (offset < 0)
         ThrowReaderException(CorruptImageError,"ImproperImageHeader");
     }
-  pcx_colormap=(unsigned char *) NULL;
   count=ReadBlob(image,1,&pcx_info.identifier);
   for (id=1; id < 1024; id++)
   {
@@ -350,10 +356,6 @@ static Image *ReadPCXImage(const ImageInfo *image_info,ExceptionInfo *exception)
     image->x_resolution=(double) pcx_info.horizontal_resolution;
     image->y_resolution=(double) pcx_info.vertical_resolution;
     image->colors=16;
-    pcx_colormap=(unsigned char *) AcquireQuantumMemory(256UL,
-      3*sizeof(*pcx_colormap));
-    if (pcx_colormap == (unsigned char *) NULL)
-      ThrowReaderException(ResourceLimitError,"MemoryAllocationFailed");
     count=ReadBlob(image,3*image->colors,pcx_colormap);
     pcx_info.reserved=(unsigned char) ReadBlobByte(image);
     pcx_info.planes=(unsigned char) ReadBlobByte(image);
@@ -385,6 +387,9 @@ static Image *ReadPCXImage(const ImageInfo *image_info,ExceptionInfo *exception)
     */
     pcx_packets=(unsigned long) image->rows*pcx_info.bytes_per_line*
       pcx_info.planes;
+    if ((size_t) (pcx_info.bits_per_pixel*pcx_info.planes*image->columns) >
+        (pcx_packets*8U))
+      ThrowReaderException(CorruptImageError,"ImproperImageHeader");
     pcx_pixels=(unsigned char *) AcquireQuantumMemory(pcx_packets,
       sizeof(*pcx_pixels));
     scanline=(unsigned char *) AcquireQuantumMemory(MagickMax(image->columns,
@@ -401,7 +406,7 @@ static Image *ReadPCXImage(const ImageInfo *image_info,ExceptionInfo *exception)
       {
         packet=(unsigned char) ReadBlobByte(image);
         if (EOFBlob(image) != MagickFalse)
-          break;
+          ThrowPCXException(CorruptImageError,"UnexpectedEndOfFile");
         *p++=packet;
         pcx_packets--;
       }
@@ -410,7 +415,7 @@ static Image *ReadPCXImage(const ImageInfo *image_info,ExceptionInfo *exception)
       {
         packet=(unsigned char) ReadBlobByte(image);
         if (EOFBlob(image) != MagickFalse)
-          break;
+          ThrowPCXException(CorruptImageError,"UnexpectedEndOfFile");
         if ((packet & 0xc0) != 0xc0)
           {
             *p++=packet;
@@ -420,7 +425,7 @@ static Image *ReadPCXImage(const ImageInfo *image_info,ExceptionInfo *exception)
         count=(ssize_t) (packet & 0x3f);
         packet=(unsigned char) ReadBlobByte(image);
         if (EOFBlob(image) != MagickFalse)
-          break;
+          ThrowPCXException(CorruptImageError,"UnexpectedEndOfFile");
         for ( ; count != 0; count--)
         {
           *p++=packet;
@@ -439,7 +444,7 @@ static Image *ReadPCXImage(const ImageInfo *image_info,ExceptionInfo *exception)
             Initialize image colormap.
           */
           if (image->colors > 256)
-            ThrowReaderException(CorruptImageError,"ColormapExceeds256Colors");
+            ThrowPCXException(CorruptImageError,"ColormapExceeds256Colors");
           if ((pcx_info.bits_per_pixel*pcx_info.planes) == 1)
             {
               /*
@@ -468,7 +473,6 @@ static Image *ReadPCXImage(const ImageInfo *image_info,ExceptionInfo *exception)
                   image->colormap[i].blue=ScaleCharToQuantum(*p++);
                 }
             }
-          pcx_colormap=(unsigned char *) RelinquishMagickMemory(pcx_colormap);
         }
     /*
       Convert PCX raster image to pixel packets.
@@ -624,8 +628,6 @@ static Image *ReadPCXImage(const ImageInfo *image_info,ExceptionInfo *exception)
     if (image->storage_class == PseudoClass)
       (void) SyncImage(image);
     scanline=(unsigned char *) RelinquishMagickMemory(scanline);
-    if (pcx_colormap != (unsigned char *) NULL)
-      pcx_colormap=(unsigned char *) RelinquishMagickMemory(pcx_colormap);
     pcx_pixels=(unsigned char *) RelinquishMagickMemory(pcx_pixels);
     if (EOFBlob(image) != MagickFalse)
       {
-- 
2.1.4

