Vulnerability: 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.
Vulnerability ID: CVE-2019-15140
CWE: CWE-416
Severity score: 6.4
Project: https://github.com/ImageMagick/ImageMagick
Published: 2019-08-18
File: coders/mat.c
Commit message: https://github.com/ImageMagick/ImageMagick/issues/1554
Commit author: Cristy

Vulnerable version (before fix):
 static Image *ReadMATImageV4(const ImageInfo *image_info,Image *image,      Object parser loop.     */     ldblk=ReadBlobLSBLong(image);     if ((ldblk > 9999) || (ldblk < 0))       break;     HDR.Type[3]=ldblk % 10; ldblk /= 10;  /* T digit */ static Image *ReadMATImage(const ImageInfo *image_info,ExceptionInfo *exception)     }    filepos = TellBlob(image);   while(!EOFBlob(image)) /* object parser loop */   {     Frames = 1;     if (filepos != (unsigned int) filepos)       break;     if(SeekBlob(image,filepos,SEEK_SET) != filepos) break;     /* printf("pos=%X\n",TellBlob(image)); */ static Image *ReadMATImage(const ImageInfo *image_info,ExceptionInfo *exception)     if(EOFBlob(image)) break;     MATLAB_HDR.ObjectSize = ReadBlobXXXLong(image);     if(EOFBlob(image)) break;     if((MagickSizeType) (MATLAB_HDR.ObjectSize+filepos) > GetBlobSize(image))       goto MATLAB_KO;     filepos += (MagickOffsetType) MATLAB_HDR.ObjectSize + 4 + 4;  RestoreMSCWarning           {             if (logging) (void)LogMagickEvent(CoderEvent,GetMagickModule(),               "  MAT cannot read scanrow %u from a file.", (unsigned)(MATLAB_HDR.SizeY-i-1));             goto ExitLoop;           }         if((CellType==miINT8 || CellType==miUINT8) && (MATLAB_HDR.StructureFlag & FLAG_LOGICAL))

Fixed version (after fix):
 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 */ static Image *ReadMATImage(const ImageInfo *image_info,ExceptionInfo *exception)     }    filepos = TellBlob(image);   while(filepos < GetBlobSize(image) && !EOFBlob(image)) /* object parser loop */   {     Frames = 1;     if(filepos > GetBlobSize(image) || filepos < 0)       break;     if(SeekBlob(image,filepos,SEEK_SET) != filepos) break;     /* printf("pos=%X\n",TellBlob(image)); */ static Image *ReadMATImage(const ImageInfo *image_info,ExceptionInfo *exception)     if(EOFBlob(image)) break;     MATLAB_HDR.ObjectSize = ReadBlobXXXLong(image);     if(EOFBlob(image)) break;     if((MagickSizeType) (MATLAB_HDR.ObjectSize+filepos) >= GetBlobSize(image))       goto MATLAB_KO;     filepos += (MagickOffsetType) MATLAB_HDR.ObjectSize + 4 + 4;  RestoreMSCWarning           {             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))

Patch:
patch: @@ -641,6 +641,7 @@ 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 */
@@ -961,10 +962,10 @@ static Image *ReadMATImage(const ImageInfo *image_info,ExceptionInfo *exception)
     }
 
   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)); */
@@ -973,7 +974,7 @@ static Image *ReadMATImage(const ImageInfo *image_info,ExceptionInfo *exception)
     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;
 
@@ -1276,6 +1277,7 @@ RestoreMSCWarning
           {
             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))
path: coders/mat.c