From 38b2e7d3f5a027058a92a48c440b1cf47f2d8af5 Mon Sep 17 00:00:00 2001
From: maminjie <maminjie1@huawei.com>
Date: Sat, 19 Sep 2020 17:41:12 +0800
Subject: [PATCH] ReadMPCImage(): Deal with a profile length of zero, or an
 irrationally large profile length. (CVE-2019-11010)

refers to http://hg.graphicsmagick.org/hg/GraphicsMagick/rev/a348d9661019
---
 coders/miff.c | 36 ++++++++++++++++++++++++++++--------
 coders/mpc.c  | 37 ++++++++++++++++++++++++++++---------
 2 files changed, 56 insertions(+), 17 deletions(-)

diff --git a/coders/miff.c b/coders/miff.c
index 60ad6f7..00813c4 100644
--- a/coders/miff.c
+++ b/coders/miff.c
@@ -1368,14 +1368,34 @@ static Image *ReadMIFFImage(const ImageInfo *image_info,
       {
         for (i=0; i < (long) number_of_profiles; i++)
         {
-          if (profiles[i].length == 0)
-            continue;
-          profiles[i].info=MagickAllocateMemory(unsigned char *,profiles[i].length);
-          if (profiles[i].info == (unsigned char *) NULL)
-            ThrowMIFFReaderException(CorruptImageError,UnableToReadGenericProfile,
-              image);
-          (void) ReadBlob(image,profiles[i].length,profiles[i].info);
-          (void) SetImageProfile(image,profiles[i].name,profiles[i].info,profiles[i].length);
+          if (profiles[i].length > 0)
+            {
+              if ((profiles[i].length - ((magick_off_t) profiles[i].length) == 0) &&
+                  ((BlobIsSeekable(image)
+                    && (GetBlobSize(image) - TellBlob(image)) >
+                    (magick_off_t) profiles[i].length) ||
+                   (profiles[i].length < 15*1024*1024)))
+                {
+                  profiles[i].info=MagickAllocateMemory(unsigned char *,profiles[i].length);
+                  if (profiles[i].info == (unsigned char *) NULL)
+                    ThrowMIFFReaderException(CorruptImageError,UnableToReadGenericProfile,
+                                             image);
+                  if (ReadBlob(image,profiles[i].length,profiles[i].info)
+                      != profiles[i].length)
+                    ThrowMIFFReaderException(CorruptImageError,
+                                             UnexpectedEndOfFile,
+                                             image);
+                  (void) SetImageProfile(image,profiles[i].name,profiles[i].info,profiles[i].length);
+                }
+              else
+                {
+                  (void) LogMagickEvent(CoderEvent,GetMagickModule(),
+                                        "Profile size %" MAGICK_SIZE_T_F "u is excessively large",
+                                        (MAGICK_SIZE_T ) profiles[i].length);
+                  ThrowMIFFReaderException(CorruptImageError,ImproperImageHeader,
+                                           image);
+                }
+            }          
           MagickFreeMemory(profiles[i].name);
           MagickFreeMemory(profiles[i].info);
         }
diff --git a/coders/mpc.c b/coders/mpc.c
index 3459f92..e184fd1 100644
--- a/coders/mpc.c
+++ b/coders/mpc.c
@@ -772,15 +772,34 @@ static Image *ReadMPCImage(const ImageInfo *image_info,ExceptionInfo *exception)
       {
         for (i=0; i < (long) number_of_profiles; i++)
         {
-          if (profiles[i].length == 0)
-            continue;
-          profiles[i].info=MagickAllocateMemory(unsigned char *,profiles[i].length);
-          if (profiles[i].info == (unsigned char *) NULL)
-            ThrowMPCReaderException(CorruptImageError,UnableToReadGenericProfile,
-              image);
-          (void) ReadBlob(image,profiles[i].length,profiles[i].info);
-          (void) SetImageProfile(image,profiles[i].name,profiles[i].info,
-                                 profiles[i].length);
+          if (profiles[i].length > 0)
+            {
+              if ((profiles[i].length - ((magick_off_t) profiles[i].length) == 0) &&
+                  ((BlobIsSeekable(image)
+                    && (GetBlobSize(image) - TellBlob(image)) >
+                    (magick_off_t) profiles[i].length) ||
+                   (profiles[i].length < 15*1024*1024)))
+                {
+                  profiles[i].info=MagickAllocateMemory(unsigned char *,profiles[i].length);
+                  if (profiles[i].info == (unsigned char *) NULL)
+                    ThrowMPCReaderException(CorruptImageError,UnableToReadGenericProfile,
+                                             image);
+                  if (ReadBlob(image,profiles[i].length,profiles[i].info)
+                      != profiles[i].length)
+                    ThrowMPCReaderException(CorruptImageError,
+                                             UnexpectedEndOfFile,
+                                             image);
+                  (void) SetImageProfile(image,profiles[i].name,profiles[i].info,profiles[i].length);
+                }
+              else
+                {
+                  (void) LogMagickEvent(CoderEvent,GetMagickModule(),
+                                        "Profile size %" MAGICK_SIZE_T_F "u is excessively large",
+                                        (MAGICK_SIZE_T ) profiles[i].length);
+                  ThrowMPCReaderException(CorruptImageError,ImproperImageHeader,
+                                           image);
+                }
+            }          
           MagickFreeMemory(profiles[i].name);
           MagickFreeMemory(profiles[i].info);
         }
-- 
2.23.0

