Triaging CVE-2025-27796 for Debian

Carlos Henrique Lima Melara <[email protected]> Mon, 31 Mar 2025 11:53:02 -0300
Newsgroups gmane.comp.video.graphicsmagick.bugs
Message-ID <kfe7nz5dusvd5mc5b4wva333mhfb5dgipr7ugdx73qzrpu46lv@ie3usmmm52z6>
Hi,

I'm triaging graphicsmagick's CVE-2025-27796 and would like to request a
second opinion from the people who actually know the code. This CVE's
description is "ReadWPGImage in WPG in GraphicsMagick before 1.3.46
mishandles palette buffer allocation, resulting in out-of-bounds access
to heap memory in ReadBlob". The CVE links to bug 750 [1] on sourceforge
but it's not public at the moment.

My analysis indicates the issue happens on the following snippet of code
[2] from ReadWPGImage().

[...]
if(pPalette!=NULL &&
   PaletteAllocBytes < 4*(WPG_Palette.StartIndex+WPG_Palette.NumOfEntries))
{
  MagickFreeResourceLimitedMemory(pPalette);
  PaletteAllocBytes = 0;
}
if(pPalette==NULL)
{
  PaletteItems = WPG_Palette.NumOfEntries;
  PaletteAllocBytes = 4*(WPG_Palette.StartIndex+WPG_Palette.NumOfEntries);
  if(PaletteAllocBytes < 4*256) PaletteAllocBytes = 4*256;
  pPalette = MagickAllocateResourceLimitedMemory(unsigned char *,(size_t)PaletteAllocBytes);
  if(pPalette==NULL)
      ThrowReaderException(ResourceLimitError,MemoryAllocationFailed,image);
  for(i=0; i<=255; i++)
  {
    pPalette[4*i] = WPG1_Palette[i].Red;
    pPalette[4*i+1] = WPG1_Palette[i].Green;
    pPalette[4*i+2] = WPG1_Palette[i].Blue;
    pPalette[4*i+3] = OpaqueOpacity;
  }
}
if(ReadBlob(image,(size_t) PaletteItems*4,pPalette+((size_t)4*WPG_Palette.StartIndex)) != (size_t) PaletteItems*4)
{
  MagickFreeResourceLimitedMemory(pPalette);
  ThrowReaderException(ResourceLimitError,MemoryAllocationFailed,image);
}
break;
[...]

Looking at the code before the fix we see that when pPalette is already
allocated but is smaller than
4*(WPG_Palette.StartIndex+WPG_Palette.NumOfEntries), it
MagickFreeResourceLimitedMemory (which doesn't set pPallete to NULL!)
which sets PaletteAllocBytes to 0. Now the second if (if(pPalette==NULL))
is skipped because pPallete isn't NULL and it proceeds to
ReadBlob(image,(size_t) PaletteItems*4,
pPalette+((size_t)4*WPG_Palette.StartIndex). The third argument to that
function "Specifies an area to place the information requested from the
file", but it's a pointer to a 0-sized buffer because of
MagickFreeResourceLimitedMemory(pPalette) and hence the "out-of-bounds
access to heap memory in ReadBlob".

It was introduced in a2be6a9 [3] (only present in 1.3.43 and afterwards).
Before that, it used already allocated buffers in the image object so
the vulnerability wouldn't be present.

Can you confirm the analysis is correct and the vulnerability is only
present after a2be6a9 [3] (v1.3.43 and afterwards)?

Cheers,
Charles

[1] https://sourceforge.net/p/graphicsmagick/bugs/750/
[2] https://foss.heptapod.net/graphicsmagick/graphicsmagick/-/blob/3b7fcd60f498cfadda813e0e76d159c5d08f190a/coders/wpg.c#L1707
[3] https://foss.heptapod.net/graphicsmagick/graphicsmagick/-/commit/a2be6a996a8c190bc75db02a74a93dcab813e9c4