CVE-2019-7397: Missing Release of Memory after Effective Lifetime (CWE-401)
value: In ImageMagick before 7.0.8-25 and GraphicsMagick through 1.3.31, several memory leaks exist in WritePDFImage in coders/pdf.c.
CWE description: The product does not sufficiently track and release allocated memory after it has been used, which slowly consumes remaining memory.
CVSS v3 base score: 7.5
Published: 2019-02-05T00:29Z
Repository: https://github.com/ImageMagick/ImageMagick
Language: C
Files changed: coders/pdf.c
Commit date: 2019-01-20 10:17:27 -0500
Commit message: https://github.com/ImageMagick/ImageMagick/issues/1454

Diff: diff --git a/coders/pdf.c b/coders/pdf.c
index 4c5708ee76b1..cf31b270a8d8 100644
--- a/coders/pdf.c
+++ b/coders/pdf.c
@@ -1899,20 +1899,22 @@ RestoreMSCWarning
           case JPEGCompression:
           {
             status=InjectImageBlob(image_info,image,image,"jpeg",exception);
             if (status == MagickFalse)
               {
+                xref=(MagickOffsetType *) RelinquishMagickMemory(xref);
                 (void) CloseBlob(image);
                 return(MagickFalse);
               }
             break;
           }
           case JPEG2000Compression:
           {
             status=InjectImageBlob(image_info,image,image,"jp2",exception);
             if (status == MagickFalse)
               {
+                xref=(MagickOffsetType *) RelinquishMagickMemory(xref);
                 (void) CloseBlob(image);
                 return(MagickFalse);
               }
             break;
           }
@@ -1962,10 +1964,11 @@ RestoreMSCWarning
               else
                 status=PackbitsEncodeImage(image,length,pixels,exception);
             pixel_info=RelinquishVirtualMemory(pixel_info);
             if (status == MagickFalse)
               {
+                xref=(MagickOffsetType *) RelinquishMagickMemory(xref);
                 (void) CloseBlob(image);
                 return(MagickFalse);
               }
             break;
           }
@@ -2008,20 +2011,22 @@ RestoreMSCWarning
           case JPEGCompression:
           {
             status=InjectImageBlob(image_info,image,image,"jpeg",exception);
             if (status == MagickFalse)
               {
+                xref=(MagickOffsetType *) RelinquishMagickMemory(xref);
                 (void) CloseBlob(image);
                 return(MagickFalse);
               }
             break;
           }
           case JPEG2000Compression:
           {
             status=InjectImageBlob(image_info,image,image,"jp2",exception);
             if (status == MagickFalse)
               {
+                xref=(MagickOffsetType *) RelinquishMagickMemory(xref);
                 (void) CloseBlob(image);
                 return(MagickFalse);
               }
             break;
           }
@@ -2036,14 +2041,11 @@ RestoreMSCWarning
             */
             length=(size_t) number_pixels;
             length*=image->colorspace == CMYKColorspace ? 4UL : 3UL;
             pixel_info=AcquireVirtualMemory(length,sizeof(*pixels));
             if (pixel_info == (MemoryInfo *) NULL)
-              {
-                xref=(MagickOffsetType *) RelinquishMagickMemory(xref);
-                ThrowPDFException(ResourceLimitError,"MemoryAllocationFailed");
-              }
+              ThrowPDFException(ResourceLimitError,"MemoryAllocationFailed");
             pixels=(unsigned char *) GetVirtualMemoryBlob(pixel_info);
             /*
               Dump runoffset encoded pixels.
             */
             q=pixels;
@@ -2079,10 +2081,11 @@ RestoreMSCWarning
               else
                 status=PackbitsEncodeImage(image,length,pixels,exception);
             pixel_info=RelinquishVirtualMemory(pixel_info);
             if (status == MagickFalse)
               {
+                xref=(MagickOffsetType *) RelinquishMagickMemory(xref);
                 (void) CloseBlob(image);
                 return(MagickFalse);
               }
             break;
           }
@@ -2136,15 +2139,11 @@ RestoreMSCWarning
                 Allocate pixel array.
               */
               length=(size_t) number_pixels;
               pixel_info=AcquireVirtualMemory(length,sizeof(*pixels));
               if (pixel_info == (MemoryInfo *) NULL)
-                {
-                  xref=(MagickOffsetType *) RelinquishMagickMemory(xref);
-                  ThrowPDFException(ResourceLimitError,
-                    "MemoryAllocationFailed");
-                }
+                ThrowPDFException(ResourceLimitError,"MemoryAllocationFailed");
               pixels=(unsigned char *) GetVirtualMemoryBlob(pixel_info);
               /*
                 Dump Runlength encoded pixels.
               */
               q=pixels;
@@ -2176,10 +2175,11 @@ RestoreMSCWarning
                 else
                   status=PackbitsEncodeImage(image,length,pixels,exception);
               pixel_info=RelinquishVirtualMemory(pixel_info);
               if (status == MagickFalse)
                 {
+                  xref=(MagickOffsetType *) RelinquishMagickMemory(xref);
                   (void) CloseBlob(image);
                   return(MagickFalse);
                 }
               break;
             }
@@ -2424,20 +2424,22 @@ RestoreMSCWarning
           {
             status=InjectImageBlob(image_info,image,tile_image,"jpeg",
               exception);
             if (status == MagickFalse)
               {
+                xref=(MagickOffsetType *) RelinquishMagickMemory(xref);
                 (void) CloseBlob(image);
                 return(MagickFalse);
               }
             break;
           }
           case JPEG2000Compression:
           {
             status=InjectImageBlob(image_info,image,tile_image,"jp2",exception);
             if (status == MagickFalse)
               {
+                xref=(MagickOffsetType *) RelinquishMagickMemory(xref);
                 (void) CloseBlob(image);
                 return(MagickFalse);
               }
             break;
           }
@@ -2485,10 +2487,11 @@ RestoreMSCWarning
               else
                 status=PackbitsEncodeImage(image,length,pixels,exception);
             pixel_info=RelinquishVirtualMemory(pixel_info);
             if (status == MagickFalse)
               {
+                xref=(MagickOffsetType *) RelinquishMagickMemory(xref);
                 (void) CloseBlob(image);
                 return(MagickFalse);
               }
             break;
           }
@@ -2526,20 +2529,22 @@ RestoreMSCWarning
           {
             status=InjectImageBlob(image_info,image,tile_image,"jpeg",
               exception);
             if (status == MagickFalse)
               {
+                xref=(MagickOffsetType *) RelinquishMagickMemory(xref);
                 (void) CloseBlob(image);
                 return(MagickFalse);
               }
             break;
           }
           case JPEG2000Compression:
           {
             status=InjectImageBlob(image_info,image,tile_image,"jp2",exception);
             if (status == MagickFalse)
               {
+                xref=(MagickOffsetType *) RelinquishMagickMemory(xref);
                 (void) CloseBlob(image);
                 return(MagickFalse);
               }
             break;
           }
@@ -2591,10 +2596,11 @@ RestoreMSCWarning
               else
                 status=PackbitsEncodeImage(image,length,pixels,exception);
             pixel_info=RelinquishVirtualMemory(pixel_info);
             if (status == MagickFalse)
               {
+                xref=(MagickOffsetType *) RelinquishMagickMemory(xref);
                 (void) CloseBlob(image);
                 return(MagickFalse);
               }
             break;
           }
@@ -2679,10 +2685,11 @@ RestoreMSCWarning
                 else
                   status=PackbitsEncodeImage(image,length,pixels,exception);
               pixel_info=RelinquishVirtualMemory(pixel_info);
               if (status == MagickFalse)
                 {
+                  xref=(MagickOffsetType *) RelinquishMagickMemory(xref);
                   (void) CloseBlob(image);
                   return(MagickFalse);
                 }
               break;
             }
@@ -2891,10 +2898,11 @@ RestoreMSCWarning
               else
                 status=PackbitsEncodeImage(image,length,pixels,exception);
             pixel_info=RelinquishVirtualMemory(pixel_info);
             if (status == MagickFalse)
               {
+                xref=(MagickOffsetType *) RelinquishMagickMemory(xref);
                 (void) CloseBlob(image);
                 return(MagickFalse);
               }
             break;
           }

Vulnerable code:               {
                xref=(MagickOffsetType *) RelinquishMagickMemory(xref);
                ThrowPDFException(ResourceLimitError,"MemoryAllocationFailed");
              }
                {
                  xref=(MagickOffsetType *) RelinquishMagickMemory(xref);
                  ThrowPDFException(ResourceLimitError,
                    "MemoryAllocationFailed");
                }
Fixed code:                 xref=(MagickOffsetType *) RelinquishMagickMemory(xref);
                xref=(MagickOffsetType *) RelinquishMagickMemory(xref);
                xref=(MagickOffsetType *) RelinquishMagickMemory(xref);
                xref=(MagickOffsetType *) RelinquishMagickMemory(xref);
                xref=(MagickOffsetType *) RelinquishMagickMemory(xref);
              ThrowPDFException(ResourceLimitError,"MemoryAllocationFailed");
                xref=(MagickOffsetType *) RelinquishMagickMemory(xref);
                ThrowPDFException(ResourceLimitError,"MemoryAllocationFailed");
                  xref=(MagickOffsetType *) RelinquishMagickMemory(xref);
                xref=(MagickOffsetType *) RelinquishMagickMemory(xref);
                xref=(MagickOffsetType *) RelinquishMagickMemory(xref);
                xref=(MagickOffsetType *) RelinquishMagickMemory(xref);
                xref=(MagickOffsetType *) RelinquishMagickMemory(xref);
                xref=(MagickOffsetType *) RelinquishMagickMemory(xref);
                xref=(MagickOffsetType *) RelinquishMagickMemory(xref);
                  xref=(MagickOffsetType *) RelinquishMagickMemory(xref);
                xref=(MagickOffsetType *) RelinquishMagickMemory(xref);