CVE-2019-13311: Missing Release of Memory after Effective Lifetime (CWE-401)
value: ImageMagick 7.0.8-50 Q16 has memory leaks at AcquireMagickMemory because of a wand/mogrify.c error.
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: 6.5
Published: 2019-07-05T01:15Z
Repository: https://github.com/ImageMagick/ImageMagick6
Language: C
Files changed: wand/mogrify.c
Commit date: 2019-07-01 19:53:22 -0400
Commit message: https://github.com/ImageMagick/ImageMagick/issues/1623

Diff: diff --git a/wand/mogrify.c b/wand/mogrify.c
index fca494d2cca..430446a0106 100644
--- a/wand/mogrify.c
+++ b/wand/mogrify.c
@@ -7842,10 +7842,13 @@ WandExport MagickBooleanType MogrifyImageList(ImageInfo *image_info,
             (void) SyncImagesSettings(mogrify_info,*images);
             image=RemoveFirstImageFromList(images);
             clut_image=RemoveFirstImageFromList(images);
             if (clut_image == (Image *) NULL)
               {
+                (void) ThrowMagickException(exception,GetMagickModule(),
+                  OptionError,"ImageSequenceRequired","`%s'",option);
+                image=DestroyImage(image);
                 status=MagickFalse;
                 break;
               }
             (void) ClutImageChannel(image,channel,clut_image);
             clut_image=DestroyImage(clut_image);
@@ -7886,13 +7889,10 @@ WandExport MagickBooleanType MogrifyImageList(ImageInfo *image_info,
             *images=combine_image;
             break;
           }
         if (LocaleCompare("compare",option+1) == 0)
           {
-            const char
-              *option;
-
             double
               distortion;
 
             Image
               *difference_image,
@@ -7909,10 +7909,13 @@ WandExport MagickBooleanType MogrifyImageList(ImageInfo *image_info,
             (void) SyncImagesSettings(mogrify_info,*images);
             image=RemoveFirstImageFromList(images);
             reconstruct_image=RemoveFirstImageFromList(images);
             if (reconstruct_image == (Image *) NULL)
               {
+                (void) ThrowMagickException(exception,GetMagickModule(),
+                  OptionError,"ImageSequenceRequired","`%s'",option);
+                image=DestroyImage(image);
                 status=MagickFalse;
                 break;
               }
             metric=UndefinedMetric;
             option=GetImageOption(image_info,"metric");
@@ -7964,10 +7967,13 @@ WandExport MagickBooleanType MogrifyImageList(ImageInfo *image_info,
             (void) SyncImagesSettings(mogrify_info,*images);
             image=RemoveFirstImageFromList(images);
             composite_image=RemoveFirstImageFromList(images);
             if (composite_image == (Image *) NULL)
               {
+                (void) ThrowMagickException(exception,GetMagickModule(),
+                  OptionError,"ImageSequenceRequired","`%s'",option);
+                image=DestroyImage(image);
                 status=MagickFalse;
                 break;
               }
             (void) TransformImage(&composite_image,(char *) NULL,
               composite_image->geometry);
@@ -8195,10 +8201,13 @@ WandExport MagickBooleanType MogrifyImageList(ImageInfo *image_info,
             (void) SyncImagesSettings(mogrify_info,*images);
             image=RemoveFirstImageFromList(images);
             hald_image=RemoveFirstImageFromList(images);
             if (hald_image == (Image *) NULL)
               {
+                (void) ThrowMagickException(exception,GetMagickModule(),
+                  OptionError,"ImageSequenceRequired","`%s'",option);
+                image=DestroyImage(image);
                 status=MagickFalse;
                 break;
               }
             (void) HaldClutImageChannel(image,channel,hald_image);
             hald_image=DestroyImage(hald_image);
@@ -8225,15 +8234,20 @@ WandExport MagickBooleanType MogrifyImageList(ImageInfo *image_info,
             (void) SyncImagesSettings(mogrify_info,*images);
             magnitude_image=RemoveFirstImageFromList(images);
             phase_image=RemoveFirstImageFromList(images);
             if (phase_image == (Image *) NULL)
               {
+                (void) ThrowMagickException(exception,GetMagickModule(),
+                  OptionError,"ImageSequenceRequired","`%s'",option);
+                magnitude_image=DestroyImage(magnitude_image);
                 status=MagickFalse;
                 break;
               }
             fourier_image=InverseFourierTransformImage(magnitude_image,
               phase_image,*option == '-' ? MagickTrue : MagickFalse,exception);
+            magnitude_image=DestroyImage(magnitude_image);
+            phase_image=DestroyImage(phase_image);
             if (fourier_image == (Image *) NULL)
               break;
             if (*images != (Image *) NULL)
               *images=DestroyImageList(*images);
             *images=fourier_image;

Vulnerable code:             const char
              *option;

Fixed code:                 (void) ThrowMagickException(exception,GetMagickModule(),
                  OptionError,"ImageSequenceRequired","`%s'",option);
                image=DestroyImage(image);
                (void) ThrowMagickException(exception,GetMagickModule(),
                  OptionError,"ImageSequenceRequired","`%s'",option);
                image=DestroyImage(image);
                (void) ThrowMagickException(exception,GetMagickModule(),
                  OptionError,"ImageSequenceRequired","`%s'",option);
                image=DestroyImage(image);
                (void) ThrowMagickException(exception,GetMagickModule(),
                  OptionError,"ImageSequenceRequired","`%s'",option);
                image=DestroyImage(image);
                (void) ThrowMagickException(exception,GetMagickModule(),
                  OptionError,"ImageSequenceRequired","`%s'",option);
                magnitude_image=DestroyImage(magnitude_image);
            magnitude_image=DestroyImage(magnitude_image);
            phase_image=DestroyImage(phase_image);