CVE-2017-12664 (published 2017-08-07T21:29Z)

ImageMagick 7.0.6-2 has a memory leak vulnerability in WritePALMImage in coders/palm.c.

Severity: MEDIUM
CVSS v2 base score: 6.8 (AV:N/AC:M/Au:N/C:P/I:P/A:P)
CVSS v3 base score: 8.8, HIGH (CVSS:3.1/AV:N/AC:L/PR:N/UI:R/S:U/C:H/I:H/A:H)

Weakness information:
cwe_id: CWE-772
cwe_name: Missing Release of Resource after Effective Lifetime
description: The product does not release a resource after its effective lifetime has ended, i.e., after the resource is no longer needed.
extended_description: When a resource is not released after use, it can allow attackers to cause a denial of service by causing the allocation of resources without triggering their release. Frequently-affected resources include memory, CPU, disk space, power or battery, etc.
         

Fix information:
repo_url: https://github.com/ImageMagick/ImageMagick
commit_details: repo_url: https://github.com/ImageMagick/ImageMagick
author: Cristy
author_date: 2017-07-17 13:47:41-04:00
msg: https://github.com/ImageMagick/ImageMagick/issues/574
repository: repo_url: https://github.com/ImageMagick/ImageMagick
repo_name: ImageMagick/ImageMagick
description: 🧙‍♂️ ImageMagick 7
repo_language: C
owner: ImageMagick
file_changes: filename: quantize.c
change_type: ModificationType.MODIFY
diff: @@ -3329,8 +3329,11 @@ static MagickBooleanType SetGrayscaleImage(Image *image,
       (void) ResetMagickMemory(colormap_index,(-1),MaxColormapSize*
         sizeof(*colormap_index));
       if (AcquireImageColormap(image,MaxColormapSize,exception) == MagickFalse)
-        ThrowBinaryException(ResourceLimitError,"MemoryAllocationFailed",
-          image->filename);
+        {
+          colormap_index=(ssize_t *) RelinquishMagickMemory(colormap_index);
+          ThrowBinaryException(ResourceLimitError,"MemoryAllocationFailed",
+            image->filename);
+        }
       image->colors=0;
       status=MagickTrue;
       image_view=AcquireAuthenticCacheView(image,exception);

programming_language: Matlab
filename: palm.c
change_type: ModificationType.MODIFY
diff: @@ -278,7 +278,7 @@ static Image *ReadPALMImage(const ImageInfo *image_info,
     y;
 
   unsigned char
-    *lastrow,
+    *last_row,
     *one_row,
     *ptr;
 
@@ -408,12 +408,12 @@ static Image *ReadPALMImage(const ImageInfo *image_info,
       2*image->columns),sizeof(*one_row));
     if (one_row == (unsigned char *) NULL)
       ThrowReaderException(ResourceLimitError,"MemoryAllocationFailed");
-    lastrow=(unsigned char *) NULL;
+    last_row=(unsigned char *) NULL;
     if (compressionType == PALM_COMPRESSION_SCANLINE)
       {
-        lastrow=(unsigned char *) AcquireQuantumMemory(MagickMax(bytes_per_row,
-          2*image->columns),sizeof(*lastrow));
-        if (lastrow == (unsigned char *) NULL)
+        last_row=(unsigned char *) AcquireQuantumMemory(MagickMax(bytes_per_row,
+          2*image->columns),sizeof(*last_row));
+        if (last_row == (unsigned char *) NULL)
           ThrowReaderException(ResourceLimitError,"MemoryAllocationFailed");
       }
     mask=(size_t) (1U << bits_per_pixel)-1;
@@ -464,10 +464,10 @@ static Image *ReadPALMImage(const ImageInfo *image_info,
                   if ((y == 0) || (count & (one << (7 - bit))))
                     one_row[i+bit]=(unsigned char) ReadBlobByte(image);
                   else
-                    one_row[i+bit]=lastrow[i+bit];
+                    one_row[i+bit]=last_row[i+bit];
                 }
               }
-              (void) CopyMagickMemory(lastrow, one_row, bytes_per_row);
+              (void) CopyMagickMemory(last_row, one_row, bytes_per_row);
             }
         }
       ptr=one_row;
@@ -480,7 +480,7 @@ static Image *ReadPALMImage(const ImageInfo *image_info,
             {
               one_row=(unsigned char *) RelinquishMagickMemory(one_row);
               if (compressionType == PALM_COMPRESSION_SCANLINE)
-                lastrow=(unsigned char *) RelinquishMagickMemory(lastrow);
+                last_row=(unsigned char *) RelinquishMagickMemory(last_row);
               ThrowReaderException(CorruptImageError,"CorruptImage");
             }
           for (x=0; x < (ssize_t) image->columns; x++)
@@ -506,7 +506,7 @@ static Image *ReadPALMImage(const ImageInfo *image_info,
               {
                 one_row=(unsigned char *) RelinquishMagickMemory(one_row);
                 if (compressionType == PALM_COMPRESSION_SCANLINE)
-                  lastrow=(unsigned char *) RelinquishMagickMemory(lastrow);
+                  last_row=(unsigned char *) RelinquishMagickMemory(last_row);
                 ThrowReaderException(CorruptImageError,"CorruptImage");
               }
             index=(Quantum) (mask-(((*ptr) & (mask << bit)) >> bit));
@@ -543,7 +543,7 @@ static Image *ReadPALMImage(const ImageInfo *image_info,
       }
     one_row=(unsigned char *) RelinquishMagickMemory(one_row);
     if (compressionType == PALM_COMPRESSION_SCANLINE)
-      lastrow=(unsigned char *) RelinquishMagickMemory(lastrow);
+      last_row=(unsigned char *) RelinquishMagickMemory(last_row);
     if (EOFBlob(image) != MagickFalse)
       {
         ThrowFileException(exception,CorruptImageError,"UnexpectedEndOfFile",
@@ -718,7 +718,7 @@ static MagickBooleanType WritePALMImage(const ImageInfo *image_info,
     bit,
     byte,
     color,
-    *lastrow,
+    *last_row,
     *one_row,
     *ptr,
     version;
@@ -861,15 +861,24 @@ static MagickBooleanType WritePALMImage(const ImageInfo *image_info,
       }
     if (flags & PALM_IS_COMPRESSED_FLAG)
       (void) WriteBlobMSBShort(image,0);  /* fill in size later */
-    lastrow=(unsigned char *) NULL;
+    last_row=(unsigned char *) NULL;
     if (image_info->compression == FaxCompression)
-      lastrow=(unsigned char *) AcquireQuantumMemory(bytes_per_row,
-        sizeof(*lastrow));
-      /* TODO check whether memory really was acquired? */
+      {
+        last_row=(unsigned char *) AcquireQuantumMemory(bytes_per_row,
+          sizeof(*last_row));
+        if (last_row == (unsigned char *) NULL)
+          {
+            quantize_info=DestroyQuantizeInfo(quantize_info);
+            ThrowWriterException(ResourceLimitError,"MemoryAllocationFailed");
+          }
+      }
     one_row=(unsigned char *) AcquireQuantumMemory(bytes_per_row,
       sizeof(*one_row));
     if (one_row == (unsigned char *) NULL)
-      ThrowWriterException(ResourceLimitError,"MemoryAllocationFailed");
+      {
+        quantize_info=DestroyQuantizeInfo(quantize_info);
+        ThrowWriterException(ResourceLimitError,"MemoryAllocationFailed");
+      }
     for (y=0; y < (ssize_t) image->rows; y++)
     {
       ptr=one_row;
@@ -949,7 +958,7 @@ static MagickBooleanType WritePALMImage(const ImageInfo *image_info,
               tptr = tmpbuf;
               for (bit=0, byte=0; bit < (unsigned char) MagickMin(8,(ssize_t) bytes_per_row-x); bit++)
               {
-                if ((y == 0) || (lastrow[x + bit] != one_row[x + bit]))
+                if ((y == 0) || (last_row[x + bit] != one_row[x + bit]))
                   {
                     byte |= (1 << (7 - bit));
                     *tptr++ = (char) one_row[x + bit];
@@ -958,7 +967,7 @@ static MagickBooleanType WritePALMImage(const ImageInfo *image_info,
               (void) WriteBlobByte(image, byte);
               (void) WriteBlob(image,tptr-tmpbuf,(unsigned char *) tmpbuf);
             }
-            (void) CopyMagickMemory(lastrow,one_row,bytes_per_row);
+            (void) CopyMagickMemory(last_row,one_row,bytes_per_row);
           }
         else
           (void) WriteBlob(image,bytes_per_row,one_row);
@@ -974,9 +983,12 @@ static MagickBooleanType WritePALMImage(const ImageInfo *image_info,
       {
         offset=SeekBlob(image,currentOffset+20,SEEK_SET);
         (void) WriteBlobByte(image,0);  /* reserved by Palm */
-        (void) WriteBlobByte(image,(unsigned char) ((31*transpix.red)/QuantumRange));
-        (void) WriteBlobByte(image,(unsigned char) ((63*transpix.green)/QuantumRange));
-        (void) WriteBlobByte(image,(unsigned char) ((31*transpix.blue)/QuantumRange));
+        (void) WriteBlobByte(image,(unsigned char) ((31*transpix.red)/
+          QuantumRange));
+        (void) WriteBlobByte(image,(unsigned char) ((63*transpix.green)/
+          QuantumRange));
+        (void) WriteBlobByte(image,(unsigned char) ((31*transpix.blue)/
+          QuantumRange));
       }
     if (flags & PALM_IS_COMPRESSED_FLAG)  /* fill in size now */
       {
@@ -986,8 +998,8 @@ static MagickBooleanType WritePALMImage(const ImageInfo *image_info,
       }
     if (one_row != (unsigned char *) NULL) 
       one_row=(unsigned char *) RelinquishMagickMemory(one_row);
-    if (lastrow != (unsigned char *) NULL) 
-      lastrow=(unsigned char *) RelinquishMagickMemory(lastrow);
+    if (last_row != (unsigned char *) NULL) 
+      last_row=(unsigned char *) RelinquishMagickMemory(last_row);
     if (GetNextImageInList(image) == (Image *) NULL)
       break;
     /* padding to 4 byte word */

programming_language: Erlang