CVE-2023-34474: Out-of-bounds Write (CWE-787)
value: A heap-based buffer overflow issue was discovered in ImageMagick's ReadTIM2ImageData() function in coders/tim2.c. A local attacker could trick the user in opening specially crafted file, triggering an out-of-bounds read error, allowing an application to crash, resulting in a denial of service.
CWE description: The product writes data past the end, or before the beginning, of the intended buffer.
CVSS v3 base score: 5.5
Published: 2023-06-16T20:15Z
Repository: https://github.com/ImageMagick/ImageMagick
Language: C
Files changed: MagickCore/profile.c, coders/tim2.c
Commit date: 2023-05-15 14:22:11 -0400
Commit message: carefully crafted image files (TIM2, JPEG) no longer overflow buffer nor use heap after free (thanks to Juzhi Lu, Zhen Zhou, Likang Luo of NSFOCUS Security Team)

Diff: diff --git a/MagickCore/profile.c b/MagickCore/profile.c
index 57909092d264..382583a52485 100644
--- a/MagickCore/profile.c
+++ b/MagickCore/profile.c
@@ -2456,15 +2456,16 @@ static void ReplaceXmpValue(StringInfo *profile,size_t start,size_t end,
   value_length=strlen(value);
   new_length=length-(end-start)+value_length;
   if (new_length > length)
     SetStringInfoLength(profile,new_length);
   datum=(char *) GetStringInfoDatum(profile);
-  memmove(datum+start+value_length,datum+end,length-end);
-  memcpy(datum+start,value,value_length);
+  (void) memmove(datum+start+value_length,datum+end,length-end);
+  (void) memcpy(datum+start,value,value_length);
   if (new_length < length)
     {
       SetStringInfoLength(profile,new_length);
+      datum=(char *) GetStringInfoDatum(profile);
       *(datum+new_length)='\0';
     }
 }
 
 static MagickBooleanType GetXmpOffsets(const StringInfo *profile,
diff --git a/coders/tim2.c b/coders/tim2.c
index 0445985dcc04..d30afaf05d6b 100644
--- a/coders/tim2.c
+++ b/coders/tim2.c
@@ -515,14 +515,16 @@ static MagickBooleanType ReadTIM2ImageData(const ImageInfo *image_info,
       *clut_data;
 
     /*
       * ### Read CLUT Data ###
       */
-    clut_data=(unsigned char *) AcquireQuantumMemory(1,header->clut_size);
+    clut_data=(unsigned char *) AcquireQuantumMemory(2,
+      MagickMax(header->clut_size,image->colors));
     if (clut_data == (unsigned char *) NULL)
       ThrowBinaryException(ResourceLimitError,"MemoryAllocationFailed",
         image_info->filename);
+    (void) memset(clut_data,0,2*MagickMax(header->clut_size,image->colors));
     count=ReadBlob(image,header->clut_size,clut_data);
     if (count != (ssize_t) (header->clut_size))
       {
         clut_data=(unsigned char *) RelinquishMagickMemory(clut_data);
         ThrowBinaryException(CorruptImageError,"InsufficientImageDataInFile",

Vulnerable code:   memmove(datum+start+value_length,datum+end,length-end);
  memcpy(datum+start,value,value_length);
    clut_data=(unsigned char *) AcquireQuantumMemory(1,header->clut_size);
Fixed code:   (void) memmove(datum+start+value_length,datum+end,length-end);
  (void) memcpy(datum+start,value,value_length);
      datum=(char *) GetStringInfoDatum(profile);
    clut_data=(unsigned char *) AcquireQuantumMemory(2,
      MagickMax(header->clut_size,image->colors));
    (void) memset(clut_data,0,2*MagickMax(header->clut_size,image->colors));