CVE-2019-15140: Use After Free (CWE-416)
value: coders/mat.c in ImageMagick 7.0.8-43 Q16 allows remote attackers to cause a denial of service (use-after-free and application crash) or possibly have unspecified other impact by crafting a Matlab image file that is mishandled in ReadImage in MagickCore/constitute.c.
CWE description: The product reuses or references memory after it has been freed. At some point afterward, the memory may be allocated again and saved in another pointer, while the original pointer references a location somewhere within the new allocation. Any operations using the original pointer are no longer valid because the memory "belongs" to the code that operates on the new pointer.
CVSS v3 base score: 8.8
Published: 2019-08-18T19:15Z
Repository: https://github.com/ImageMagick/ImageMagick
Language: C
Files changed: coders/mat.c
Commit date: 2019-04-27 08:32:23 -0400
Commit message: https://github.com/ImageMagick/ImageMagick/issues/1554

Diff: diff --git a/coders/mat.c b/coders/mat.c
index 776ed9a0fa39..8d704fde29f1 100644
--- a/coders/mat.c
+++ b/coders/mat.c
@@ -639,10 +639,11 @@ static Image *ReadMATImageV4(const ImageInfo *image_info,Image *image,
   {
     /*
      Object parser loop.
     */
     ldblk=ReadBlobLSBLong(image);
+    if(EOFBlob(image)) break;
     if ((ldblk > 9999) || (ldblk < 0))
       break;
     HDR.Type[3]=ldblk % 10; ldblk /= 10;  /* T digit */
     HDR.Type[2]=ldblk % 10; ldblk /= 10;  /* P digit */
     HDR.Type[1]=ldblk % 10; ldblk /= 10;  /* O digit */
@@ -959,23 +960,23 @@ MATLAB_KO:
         clone_info=DestroyImageInfo(clone_info);
       ThrowReaderException(CorruptImageError,"ImproperImageHeader");
     }
 
   filepos = TellBlob(image);
-  while(!EOFBlob(image)) /* object parser loop */
+  while(filepos < GetBlobSize(image) && !EOFBlob(image)) /* object parser loop */
   {
     Frames = 1;
-    if (filepos != (unsigned int) filepos)
+    if(filepos > GetBlobSize(image) || filepos < 0)
       break;
     if(SeekBlob(image,filepos,SEEK_SET) != filepos) break;
     /* printf("pos=%X\n",TellBlob(image)); */
 
     MATLAB_HDR.DataType = ReadBlobXXXLong(image);
     if(EOFBlob(image)) break;
     MATLAB_HDR.ObjectSize = ReadBlobXXXLong(image);
     if(EOFBlob(image)) break;
-    if((MagickSizeType) (MATLAB_HDR.ObjectSize+filepos) > GetBlobSize(image))
+    if((MagickSizeType) (MATLAB_HDR.ObjectSize+filepos) >= GetBlobSize(image))
       goto MATLAB_KO;
     filepos += (MagickOffsetType) MATLAB_HDR.ObjectSize + 4 + 4;
 
     if (clone_info != (ImageInfo *) NULL)
       clone_info=DestroyImageInfo(clone_info);
@@ -1274,10 +1275,11 @@ RestoreMSCWarning
           }
         if(ReadBlob(image2,ldblk,(unsigned char *)BImgBuff) != (ssize_t) ldblk)
           {
             if (logging) (void)LogMagickEvent(CoderEvent,GetMagickModule(),
               "  MAT cannot read scanrow %u from a file.", (unsigned)(MATLAB_HDR.SizeY-i-1));
+            ThrowReaderException(CorruptImageError,"UnexpectedEndOfFile");
             goto ExitLoop;
           }
         if((CellType==miINT8 || CellType==miUINT8) && (MATLAB_HDR.StructureFlag & FLAG_LOGICAL))
         {
           FixLogical((unsigned char *)BImgBuff,ldblk);

Vulnerable code:   while(!EOFBlob(image)) /* object parser loop */
    if (filepos != (unsigned int) filepos)
    if((MagickSizeType) (MATLAB_HDR.ObjectSize+filepos) > GetBlobSize(image))
Fixed code:     if(EOFBlob(image)) break;
  while(filepos < GetBlobSize(image) && !EOFBlob(image)) /* object parser loop */
    if(filepos > GetBlobSize(image) || filepos < 0)
    if((MagickSizeType) (MATLAB_HDR.ObjectSize+filepos) >= GetBlobSize(image))
            ThrowReaderException(CorruptImageError,"UnexpectedEndOfFile");