Version in base suite: 1.1.11-3.2 Version in overlay suite: (not present) Base version: graphicsmagick_1.1.11-3.2 Target version: graphicsmagick_1.1.11-3.2+lenny1 Base file: /org/ftp.debian.org/ftp/pool/main/g/graphicsmagick/graphicsmagick_1.1.11-3.2.dsc Target file: /org/ftp.debian.org/queue/p-u-new/graphicsmagick_1.1.11-3.2+lenny1.dsc coders/avi.c | 139 ++++++++++++++----- coders/avs.c | 71 +++++++--- coders/cineon.c | 30 +++- coders/dcm.c | 87 +++++++++--- coders/dpx.c | 15 +- coders/ept.c | 24 +-- coders/fits.c | 36 ++--- coders/mtv.c | 20 +- coders/palm.c | 34 ++++ coders/pict.c | 41 ++++- coders/rla.c | 231 +++++++++++++++++++++++++-------- coders/tga.c | 61 +++++--- graphicsmagick-1.1.11/coders/xcf.c | 21 +++ graphicsmagick-1.1.11/debian/changelog | 17 ++ magick/memory.c | 42 ++++++ magick/utility.h | 1 magick/xwindow.c | 26 ++- 17 files changed, 675 insertions(+), 221 deletions(-) diff -u graphicsmagick-1.1.11/coders/xcf.c graphicsmagick-1.1.11/coders/xcf.c --- graphicsmagick-1.1.11/coders/xcf.c +++ graphicsmagick-1.1.11/coders/xcf.c @@ -300,12 +300,23 @@ xcfdata = xcfodata = MagickAllocateMemory(XCFPixelPacket *,data_length); graydata = (unsigned char *)xcfdata; /* used by gray and indexed */ + if (xcfdata == (XCFPixelPacket *) NULL) + { + ThrowException(&image->exception,ResourceLimitError,MemoryAllocationFailed,NULL); + return False; + } nmemb_read_successfully = ReadBlob(image, data_length, xcfdata); if (nmemb_read_successfully > (ssize_t) (tile_image->columns*tile_image->rows)) ThrowBinaryException(CorruptImageError,CorruptImage,image->filename); q=SetImagePixels(tile_image,0,0,tile_image->columns,tile_image->rows); + if (q == (PixelPacket *) NULL) + { + CopyException(&image->exception,&tile_image->exception); + MagickFreeMemory(xcfodata); + return False; + } /* we have to copy the pixels individually since IM uses a different format PixelPacket on different platforms - not to mention @@ -350,6 +361,11 @@ bpp = (int) inDocInfo->bpp; xcfdata = xcfodata = MagickAllocateMemory(unsigned char *,data_length); + if (xcfdata == (unsigned char *) NULL) + { + ThrowException(&image->exception,ResourceLimitError,MemoryAllocationFailed,NULL); + return False; + } nmemb_read_successfully = ReadBlob(image, data_length, xcfdata); @@ -358,6 +374,11 @@ for (i = 0; i < bpp; i++) { q=SetImagePixels(tile_image,0,0,tile_image->columns,tile_image->rows); + if (q == (PixelPacket *) NULL) + { + CopyException(&image->exception,&tile_image->exception); + goto bogus_rle; + } size = tile_image->rows * tile_image->columns; count = 0; diff -u graphicsmagick-1.1.11/debian/changelog graphicsmagick-1.1.11/debian/changelog --- graphicsmagick-1.1.11/debian/changelog +++ graphicsmagick-1.1.11/debian/changelog @@ -1,3 +1,20 @@ +graphicsmagick (1.1.11-3.2+lenny1) stable-security; urgency=high + + * Non-maintainer upload by the Security Team. + * Fixed CVE-2008-3134: Multiple errors within the processing of various + formats can be exploited to crash the application (Closes: 491439) + * Fixed CVE-2008-6070: Multiple heap-based buffer underflows in the + ReadPALMImage function + * Fixed CVE-2008-6071: Heap-based buffer overflow in the DecodeImage function + * Fixed CVE-2008-6072: Multiple errors within the processing of XCF and + CINEON images can be exploited to crash the application. + * Fixed CVE-2008-6621: Multiple errors within the processing of DPX images + can be exploited to crash the application. + * Fixed CVE-2009-1882: Integer overflow in the XMakeImage function + (Closes: 530946) + + -- Giuseppe Iuculano Mon, 05 Oct 2009 22:11:23 +0200 + graphicsmagick (1.1.11-3.2) unstable; urgency=high * Non-maintainer upload by the Security Team: only in patch2: unchanged: --- graphicsmagick-1.1.11.orig/coders/ept.c +++ graphicsmagick-1.1.11/coders/ept.c @@ -208,14 +208,6 @@ if (status == False) ThrowReaderException(FileOpenError,UnableToOpenFile,image); /* - Open temporary output file. - */ - file=AcquireTemporaryFileStream(postscript_filename,BinaryFileIOMode); - if (file == (FILE *) NULL) - ThrowReaderTemporaryFileException(postscript_filename); - FormatString(translate_geometry,"%g %g translate\n ",0.0,0.0); - (void) fputs(translate_geometry,file); - /* Set the page geometry. */ dx_resolution=72.0; @@ -239,8 +231,19 @@ (void) ReadBlobLSBLong(image); count=ReadBlobLSBLong(image); filesize=ReadBlobLSBLong(image); + if (EOFBlob(image)) + ThrowReaderException(CorruptImageError,UnexpectedEndOfFile,image); for (i=0; i < (long) (count-12); i++) - (void) ReadBlobByte(image); + if (ReadBlobByte(image) == EOF) + ThrowReaderException(CorruptImageError,UnexpectedEndOfFile,image); + /* + Open temporary output file. + */ + file=AcquireTemporaryFileStream(postscript_filename,BinaryFileIOMode); + if (file == (FILE *) NULL) + ThrowReaderTemporaryFileException(postscript_filename); + FormatString(translate_geometry,"%g %g translate\n ",0.0,0.0); + (void) fputs(translate_geometry,file); /* Copy Postscript to temporary file. */ @@ -249,8 +252,7 @@ p=command; for (i=0; i < (long) filesize; i++) { - c=ReadBlobByte(image); - if (c == EOF) + if ((c=ReadBlobByte(image)) == EOF) break; (void) fputc(c,file); *p++=c; only in patch2: unchanged: --- graphicsmagick-1.1.11.orig/coders/tga.c +++ graphicsmagick-1.1.11/coders/tga.c @@ -119,7 +119,7 @@ Image *image; - IndexPacket + unsigned int index; long @@ -175,13 +175,14 @@ /* Read TGA header information. */ - count=ReadBlob(image,1,(char *) &tga_info.id_length); + (void) ReadBlob(image,1,(char *) &tga_info.id_length); tga_info.colormap_type=ReadBlobByte(image); tga_info.image_type=ReadBlobByte(image); + if (EOFBlob(image)) + ThrowReaderException(CorruptImageError,UnexpectedEndOfFile,image); do { - if ((count == 0) || - ((tga_info.image_type != TGAColormap) && + if (((tga_info.image_type != TGAColormap) && (tga_info.image_type != TGARGB) && (tga_info.image_type != TGAMonochrome) && (tga_info.image_type != TGARLEColormap) && @@ -200,6 +201,8 @@ tga_info.height=ReadBlobLSBShort(image); tga_info.bits_per_pixel=ReadBlobByte(image); tga_info.attributes=ReadBlobByte(image); + if (EOFBlob(image)) + ThrowReaderException(CorruptImageError,UnexpectedEndOfFile,image); (void) LogMagickEvent(CoderEvent,GetMagickModule(), "ImageType=%s CMapType=%u CMapStart=%u CMapLength=%u CMapDepth=%u\n XOffset=%u YOffset=%u Width=%u Height=%u PixelDepth=%u Attributes=0x%.2x", ((tga_info.image_type == TGAColormap) ? "Colormapped" : @@ -209,14 +212,23 @@ (tga_info.image_type == TGARLERGB) ? "Truecolor-RLE" : (tga_info.image_type == TGARLEMonochrome) ? "Monochrome-RLE" : "Unknown"), - (unsigned int) tga_info.colormap_type, - (unsigned int) tga_info.colormap_index, - (unsigned int) tga_info.colormap_length, - (unsigned int) tga_info.colormap_size, - tga_info.x_origin, tga_info.y_origin, tga_info.width, tga_info.height, + (unsigned int) tga_info.colormap_type, /* Colormap type */ + (unsigned int) tga_info.colormap_index, /* Index of first colormap entry to use */ + (unsigned int) tga_info.colormap_length, /* # of elements in colormap */ + (unsigned int) tga_info.colormap_size, /* Bits in each palette entry */ + tga_info.x_origin, tga_info.y_origin, + tga_info.width, tga_info.height, (unsigned int) tga_info.bits_per_pixel, tga_info.attributes); - + + /* + Validate depth. + */ + if (!(((tga_info.bits_per_pixel > 1) && (tga_info.bits_per_pixel < 17)) || + (tga_info.bits_per_pixel == 24 ) || + (tga_info.bits_per_pixel == 32 ))) + ThrowReaderException(CoderError,DataStorageTypeIsNotSupported,image); + /* Initialize image structure. */ @@ -304,7 +316,8 @@ if (comment == (char *) NULL) ThrowReaderException(ResourceLimitError,MemoryAllocationFailed, image); - (void) ReadBlob(image,tga_info.id_length,comment); + if(ReadBlob(image,tga_info.id_length,comment) != tga_info.id_length) + ThrowReaderException(CorruptImageError,UnexpectedEndOfFile,image); comment[tga_info.id_length]='\0'; (void) SetImageAttribute(image,"comment",comment); MagickFreeMemory(comment); @@ -369,6 +382,8 @@ image->colormap[i]=pixel; } } + if (EOFBlob(image)) + ThrowReaderException(CorruptImageError,UnexpectedEndOfFile,image); if (image_info->ping && (image_info->subrange != 0)) if (image->scene >= (image_info->subimage+image_info->subrange-1)) break; @@ -405,9 +420,11 @@ } else { - count=ReadBlob(image,1,(char *) &runlength); - if (count == 0) - ThrowReaderException(CorruptImageError,UnableToReadImageData,image); + if (ReadBlob(image,1,(char *) &runlength) != 1) + { + status=MagickFail; + break; + } flag=runlength & 0x80; if (flag != 0) runlength-=128; @@ -488,7 +505,9 @@ break; } } - if (status == False) + if (EOFBlob(image)) + status = MagickFail; + if (status == MagickFail) ThrowReaderException(CorruptImageError,UnableToReadImageData,image); if (image->storage_class == PseudoClass) indexes[x]=index; @@ -535,7 +554,7 @@ (tga_info.image_type == TGARLEColormap) || (tga_info.image_type == TGARLERGB) || (tga_info.image_type == TGARLEMonochrome)); - if (status == True) + if (!EOFBlob(image) && (status == True)) { /* Allocate next image structure. @@ -680,25 +699,25 @@ typedef struct _TargaInfo { unsigned char - id_length, + id_length, colormap_type, image_type; unsigned short - colormap_index, + colormap_index, colormap_length; unsigned char - colormap_size; + colormap_size; unsigned short - x_origin, + x_origin, y_origin, width, height; unsigned char - bits_per_pixel, + bits_per_pixel, attributes; } TargaInfo; only in patch2: unchanged: --- graphicsmagick-1.1.11.orig/coders/fits.c +++ graphicsmagick-1.1.11/coders/fits.c @@ -190,7 +190,7 @@ *p; size_t - count; + row_octets; unsigned char *fits_pixels, @@ -229,12 +229,8 @@ /* Decode image header. */ - c=ReadBlobByte(image); - if (c == EOF) - { - DestroyImage(image); - return((Image *) NULL); - } + if ((c=ReadBlobByte(image)) == EOF) + ThrowReaderException(CorruptImageError,UnexpectedEndOfFile,image); for ( ; ; ) { if (!isalnum((int) c)) @@ -252,7 +248,8 @@ { if ((p-keyword) < (MaxTextExtent-1)) *p++=c; - c=ReadBlobByte(image); + if ((c=ReadBlobByte(image)) == EOF) + ThrowReaderException(CorruptImageError,UnexpectedEndOfFile,image); } while (isalnum(c) || (c == '_')); *p='\0'; if (LocaleCompare(keyword,"END") == 0) @@ -262,7 +259,8 @@ { if (c == '=') value_expected=True; - c=ReadBlobByte(image); + if ((c=ReadBlobByte(image)) == EOF) + ThrowReaderException(CorruptImageError,UnexpectedEndOfFile,image); } if (value_expected == False) continue; @@ -271,7 +269,8 @@ { if ((p-value) < (MaxTextExtent-1)) *p++=c; - c=ReadBlobByte(image); + if ((c=ReadBlobByte(image)) == EOF) + ThrowReaderException(CorruptImageError,UnexpectedEndOfFile,image); } *p='\0'; /* @@ -299,11 +298,14 @@ fits_info.scale=atof(value); } while ((TellBlob(image) % 80) != 0) - c=ReadBlobByte(image); - c=ReadBlobByte(image); + if ((c=ReadBlobByte(image)) == EOF) + ThrowReaderException(CorruptImageError,UnexpectedEndOfFile,image); + if ((c=ReadBlobByte(image)) == EOF) + ThrowReaderException(CorruptImageError,UnexpectedEndOfFile,image); } while ((TellBlob(image) % 2880) != 0) - c=ReadBlobByte(image); + if ((c=ReadBlobByte(image)) == EOF) + ThrowReaderException(CorruptImageError,UnexpectedEndOfFile,image); /* Verify that required image information is defined. */ @@ -349,14 +351,16 @@ if (packet_size < 0) packet_size=(-packet_size); number_pixels=image->columns*image->rows; - fits_pixels=MagickAllocateMemory(unsigned char *,packet_size*number_pixels); + if ((number_pixels / image->columns) != image->rows) + ThrowReaderException(CoderError,ImageColumnOrRowSizeIsNotSupported,image); + fits_pixels=MagickAllocateMemoryElements(unsigned char *,number_pixels,packet_size); if (fits_pixels == (unsigned char *) NULL) ThrowReaderException(ResourceLimitError,MemoryAllocationFailed,image); /* Convert FITS pixels to pixel packets. */ - count=ReadBlob(image,packet_size*number_pixels,fits_pixels); - if (count == 0) + row_octets=packet_size*number_pixels; + if (ReadBlob(image,row_octets,fits_pixels) != row_octets) ThrowReaderException(CorruptImageError,InsufficientImageDataInFile, image); if ((fits_info.min_data == 0.0) && (fits_info.max_data == 0.0)) only in patch2: unchanged: --- graphicsmagick-1.1.11.orig/coders/dcm.c +++ graphicsmagick-1.1.11/coders/dcm.c @@ -2746,9 +2746,11 @@ /* Read DCM preamble. */ - count=ReadBlob(image,128,(char *) magick); - count=ReadBlob(image,4,(char *) magick); - if ((count == 0) || (LocaleNCompare((char *) magick,"DICM",4) != 0)) + if ((count=ReadBlob(image,128,(char *) magick)) != 128) + ThrowReaderException(CorruptImageError,UnexpectedEndOfFile,image); + if ((count=ReadBlob(image,4,(char *) magick)) != 4) + ThrowReaderException(CorruptImageError,UnexpectedEndOfFile,image); + if (LocaleNCompare((char *) magick,"DICM",4) != 0) (void) SeekBlob(image,0L,SEEK_SET); /* Read DCM Medical image. @@ -2780,6 +2782,8 @@ group=ReadBlobLSBShort(image); element=ReadBlobLSBShort(image); quantum=0; + if (EOFBlob(image)) + ThrowReaderException(CorruptImageError,UnexpectedEndOfFile,image); /* Find corresponding VR for this group and element. */ @@ -2788,7 +2792,8 @@ (element == dicom_info[i].element)) break; (void) strncpy(implicit_vr,dicom_info[i].vr,MaxTextExtent-1); - count=ReadBlob(image,2,(char *) explicit_vr); + if ((count=ReadBlob(image,2,(char *) explicit_vr)) != 2) + ThrowReaderException(CorruptImageError,UnexpectedEndOfFile,image); /* Check for "explicitness", but meta-file headers always explicit. */ @@ -2814,15 +2819,24 @@ (strcmp(explicit_vr,"OW") == 0) || (strcmp(explicit_vr,"SQ") == 0)) { (void) ReadBlobLSBShort(image); + if (EOFBlob(image)) + ThrowReaderException(CorruptImageError,UnexpectedEndOfFile,image); quantum=4; } } datum=0; if (quantum == 4) - datum=(long) ReadBlobLSBLong(image); - else - if (quantum == 2) + { + datum=(long) ReadBlobLSBLong(image); + if (EOFBlob(image)) + ThrowReaderException(CorruptImageError,UnexpectedEndOfFile,image); + } + else if (quantum == 2) + { datum=(long) ReadBlobLSBShort(image); + if (EOFBlob(image)) + ThrowReaderException(CorruptImageError,UnexpectedEndOfFile,image); + } quantum=0; length=1; if (datum != 0) @@ -3279,7 +3293,10 @@ { q=GetImagePixels(image,0,y,image->columns,1); if (q == (PixelPacket *) NULL) - break; + { + status=MagickFail; + break; + } for (x=0; x < (long) image->columns; x++) { switch ((int) i) @@ -3291,15 +3308,31 @@ (MaxRGB-ScaleCharToQuantum(ReadBlobByte(image))); break; default: break; } + if (EOFBlob(image)) + { + ThrowReaderException(CorruptImageError,UnexpectedEndOfFile,image); + status=MagickFail; + break; + } q++; } if (!SyncImagePixels(image)) - break; + { + status=MagickFail; + break; + } if (image->previous == (Image *) NULL) if (QuantumTick(y,image->rows)) if (!MagickMonitor(LoadImageText,y,image->rows,exception)) - break; + { + status=MagickFail; + break; + } + if (status == MagickFail) + break; } + if (status == MagickFail) + break; } } else @@ -3319,7 +3352,10 @@ { q=SetImagePixels(image,0,y,image->columns,1); if (q == (PixelPacket *) NULL) - break; + { + status=MagickFail; + break; + } indexes=GetIndexes(image); for (x=0; x < (long) image->columns; x++) { @@ -3399,24 +3435,37 @@ q->green=(Quantum) green; q->blue=(Quantum) blue; q++; + if (EOFBlob(image)) + { + ThrowReaderException(CorruptImageError,UnexpectedEndOfFile,image); + status=MagickFail; + } } if (!SyncImagePixels(image)) - break; + { + status=MagickFail; + break; + } if (image->previous == (Image *) NULL) if (QuantumTick(y,image->rows)) if (!MagickMonitor(LoadImageText,y,image->rows,exception)) - break; + { + status=MagickFail; + break; + } } - if (image->storage_class == PseudoClass) - { - if (bytes_per_pixel == 2) - (void) NormalizeImage(image); - } + if (status == MagickPass) + if (image->storage_class == PseudoClass) + { + if (bytes_per_pixel == 2) + (void) NormalizeImage(image); + } } if (EOFBlob(image)) { ThrowException(exception,CorruptImageError,UnexpectedEndOfFile, image->filename); + status=MagickFail; break; } /* @@ -3439,7 +3488,7 @@ image=SyncNextImageInList(image); status=MagickMonitor(LoadImagesText,TellBlob(image),GetBlobSize(image), exception); - if (status == False) + if (status == MagickFail) break; } } only in patch2: unchanged: --- graphicsmagick-1.1.11.orig/coders/palm.c +++ graphicsmagick-1.1.11/coders/palm.c @@ -464,6 +464,15 @@ transparentIndex = ReadBlobByte(image); compressionType = ReadBlobByte(image); (void) ReadBlobMSBShort(image); /* pad */ + if (EOFBlob(image)) + ThrowReaderException(CorruptImageError,UnexpectedEndOfFile,image); + + /* + Validate bits per pixel. + */ + if ((bits_per_pixel < 1) || + ((bits_per_pixel > 8) && (bits_per_pixel != 16))) + ThrowReaderException(CorruptImageError,UnrecognizedBitsPerPixel,image); /* Initialize image colormap. @@ -477,6 +486,8 @@ (void) ReadBlobMSBLong(image); /* size */ else (void) ReadBlobMSBShort(image); /* size */ + if (EOFBlob(image)) + ThrowReaderException(CorruptImageError,UnexpectedEndOfFile,image); } else /* is color */ if(bits_per_pixel == 8) @@ -488,9 +499,13 @@ for(i = 0; i < (long) count; i++) { ReadBlobByte(image); - image->colormap[255 - i].red = ScaleCharToQuantum(ReadBlobByte(image)); - image->colormap[255 - i].green = ScaleCharToQuantum(ReadBlobByte(image)); - image->colormap[255 - i].blue = ScaleCharToQuantum(ReadBlobByte(image)); + index=255 - i; + VerifyColormapIndex(image,index); + image->colormap[index].red = ScaleCharToQuantum(ReadBlobByte(image)); + image->colormap[index].green = ScaleCharToQuantum(ReadBlobByte(image)); + image->colormap[index].blue = ScaleCharToQuantum(ReadBlobByte(image)); + if (EOFBlob(image)) + ThrowReaderException(CorruptImageError,UnexpectedEndOfFile,image); } } for(; i < (long) (1L << bits_per_pixel); i++) @@ -506,9 +521,13 @@ transpix.green = (unsigned char) (ReadBlobByte(image) * MaxRGB / 63); transpix.blue = (unsigned char) (ReadBlobByte(image) * MaxRGB / 31); } - image->colormap[255 - i].red = ScaleCharToQuantum(PalmPalette[i][0]); - image->colormap[255 - i].green = ScaleCharToQuantum(PalmPalette[i][1]); - image->colormap[255 - i].blue = ScaleCharToQuantum(PalmPalette[i][2]); + index=255 - i; + VerifyColormapIndex(image,index); + image->colormap[index].red = ScaleCharToQuantum(PalmPalette[i][0]); + image->colormap[index].green = ScaleCharToQuantum(PalmPalette[i][1]); + image->colormap[index].blue = ScaleCharToQuantum(PalmPalette[i][2]); + if (EOFBlob(image)) + ThrowReaderException(CorruptImageError,UnexpectedEndOfFile,image); } } @@ -601,6 +620,7 @@ if (ptr - one_row >= bytes_per_row) ThrowReaderException(CorruptImageError,CorruptImage,image); index =(IndexPacket) (mask - (((*ptr) & (mask << bit)) >> bit)); + VerifyColormapIndex(image,index); indexes[x] = index; *q++ = image->colormap[index]; if (!bit) @@ -616,6 +636,8 @@ if (!SyncImagePixels(image)) break; } + if (EOFBlob(image)) + ThrowReaderException(CorruptImageError,UnexpectedEndOfFile,image); } if(flags & PALM_HAS_TRANSPARENCY_FLAG) only in patch2: unchanged: --- graphicsmagick-1.1.11.orig/coders/pict.c +++ graphicsmagick-1.1.11/coders/pict.c @@ -418,15 +418,14 @@ *q; size_t - length; + allocated_pixels, + length, + row_bytes; unsigned char *pixels, *scanline; - unsigned short - row_bytes; - unsigned long bytes_per_pixel, number_pixels, @@ -450,16 +449,17 @@ width*=image->matte ? 4 : 3; if (bytes_per_line == 0) bytes_per_line=width; - row_bytes=(unsigned short) (image->columns | 0x8000); + row_bytes=(size_t) (image->columns | 0x8000); if (image->storage_class == DirectClass) - row_bytes=(unsigned short) ((4*image->columns) | 0x8000); + row_bytes=(size_t) ((4*image->columns) | 0x8000); /* Allocate pixel and scanline buffer. */ - pixels=MagickAllocateMemory(unsigned char *,row_bytes*image->rows); + pixels=MagickAllocateMemoryElements(unsigned char *,image->rows,row_bytes); if (pixels == (unsigned char *) NULL) return((unsigned char *) NULL); - memset(pixels,0,row_bytes*image->rows); + allocated_pixels=image->rows*row_bytes; + memset(pixels,0,allocated_pixels); scanline=MagickAllocateMemory(unsigned char *,row_bytes); if (scanline == (unsigned char *) NULL) return((unsigned char *) NULL); @@ -491,7 +491,8 @@ scanline_length=ReadBlobByte(blob); if (scanline_length >= row_bytes) { - ThrowException(&image->exception,CorruptImageError,UnableToUncompressImage,"scanline length exceeds row bytes"); + ThrowException(&image->exception,CorruptImageError,UnableToUncompressImage, + "scanline length exceeds row bytes"); break; } (void) ReadBlob(blob,scanline_length,(char *) scanline); @@ -501,6 +502,13 @@ length=(scanline[j] & 0xff)+1; number_pixels=length*bytes_per_pixel; p=ExpandBuffer(scanline+j+1,&number_pixels,bits_per_pixel); + if ((q+number_pixels > pixels+allocated_pixels)) + { + ThrowException(&image->exception,CorruptImageError,UnableToUncompressImage, + "Decoded RLE pixels exceeds allocation!"); + break; + } + (void) memcpy(q,p,number_pixels); q+=number_pixels; j+=length*bytes_per_pixel+1; @@ -512,6 +520,12 @@ p=ExpandBuffer(scanline+j+1,&number_pixels,bits_per_pixel); for (i=0; i < (long) length; i++) { + if ((q+number_pixels > pixels+allocated_pixels)) + { + ThrowException(&image->exception,CorruptImageError,UnableToUncompressImage, + "Decoded RLE pixels exceeds allocation!"); + break; + } (void) memcpy(q,p,number_pixels); q+=number_pixels; } @@ -795,6 +809,15 @@ if (version != 1) ThrowReaderException(CorruptImageError,ImproperImageHeader,image); /* + Validate dimensions + */ + if ((frame.left < 0) || (frame.right < 0) || (frame.top < 0) || (frame.bottom < 0) || + (frame.left >= frame.right) || (frame.top >= frame.bottom)) + { + ThrowReaderException(CorruptImageError,ImproperImageHeader,image); + } + + /* Create black canvas. */ flags=0; only in patch2: unchanged: --- graphicsmagick-1.1.11.orig/coders/rla.c +++ graphicsmagick-1.1.11/coders/rla.c @@ -93,13 +93,13 @@ window, active_window; - short + magick_uint16_t frame, storage_type, number_channels, number_matte_channels, number_auxiliary_channels, - revision; + revision; /* aux_mask in RLB */ char gamma[16], @@ -108,7 +108,7 @@ blue_primary[24], white_point[24]; - long + magick_uint32_t job_number; char @@ -122,14 +122,20 @@ aspect_ratio[8], chan[32]; - short + magick_uint16_t field; + /* RLB varies after this point */ + + } RLAInfo; + + typedef struct _RLA3ExtraInfo + { char time[12], filter[32]; - short + magick_uint16_t bits_per_channel, matte_type, matte_bits, @@ -140,9 +146,30 @@ auxiliary[32], space[36]; - long + magick_uint32_t next; - } RLAInfo; + } RLA3ExtraInfo; + + typedef struct _RLBExtraInfo + { + magick_uint16_t + filter_type; + + magick_uint32_t + magic_number, + lut_size, + user_space_size, + wf_space_size; + + magick_uint16_t + lut_type, + mix_type, + encode_type, + padding; + + char + space[100]; + } RLBExtraInfo; Image *image; @@ -150,17 +177,15 @@ int channel, length, + number_channels, runlength; long y; - long + magick_uint32_t *scanlines; - register IndexPacket - *indexes; - register long i, x; @@ -171,10 +196,19 @@ RLAInfo rla_info; - unsigned char + RLA3ExtraInfo + rla3_extra_info; + + RLBExtraInfo + rlb_extra_info; + + MagickBool + is_rla3; + + int byte; - unsigned int + MagickPassFail status; /* @@ -186,8 +220,12 @@ assert(exception->signature == MagickSignature); image=AllocateImage(image_info); status=OpenBlob(image_info,image,ReadBinaryBlobMode,exception); - if (status == False) + if (status == MagickFail) ThrowReaderException(FileOpenError,UnableToOpenFile,image); + is_rla3=MagickFalse; + memset(&rla_info,0,sizeof(rla_info)); + memset(&rla3_extra_info,0,sizeof(rla3_extra_info)); + memset(&rlb_extra_info,0,sizeof(rlb_extra_info)); rla_info.window.left=ReadBlobMSBShort(image); rla_info.window.right=ReadBlobMSBShort(image); rla_info.window.bottom=ReadBlobMSBShort(image); @@ -202,9 +240,10 @@ rla_info.number_matte_channels=ReadBlobMSBShort(image); if (rla_info.number_channels == 0) rla_info.number_channels=3; - rla_info.number_channels+=rla_info.number_matte_channels; rla_info.number_auxiliary_channels=ReadBlobMSBShort(image); rla_info.revision=ReadBlobMSBShort(image); + if (rla_info.revision == 0xFFFE) + is_rla3=MagickTrue; (void) ReadBlob(image,16,(char *) rla_info.gamma); (void) ReadBlob(image,24,(char *) rla_info.red_primary); (void) ReadBlob(image,24,(char *) rla_info.green_primary); @@ -221,29 +260,72 @@ (void) ReadBlob(image,8,(char *) rla_info.aspect_ratio); (void) ReadBlob(image,32,(char *) rla_info.chan); rla_info.field=ReadBlobMSBShort(image); - (void) ReadBlob(image,12,(char *) rla_info.time); - (void) ReadBlob(image,32,(char *) rla_info.filter); - rla_info.bits_per_channel=ReadBlobMSBShort(image); - rla_info.matte_type=ReadBlobMSBShort(image); - rla_info.matte_bits=ReadBlobMSBShort(image); - rla_info.auxiliary_type=ReadBlobMSBShort(image); - rla_info.auxiliary_bits=ReadBlobMSBShort(image); - (void) ReadBlob(image,32,(char *) rla_info.auxiliary); - (void) ReadBlob(image,36,(char *) rla_info.space); - rla_info.next=(long) ReadBlobMSBLong(image); + if (is_rla3) + { + (void) ReadBlob(image,12,(char *) rla3_extra_info.time); + (void) ReadBlob(image,32,(char *) rla3_extra_info.filter); + rla3_extra_info.bits_per_channel=ReadBlobMSBShort(image); + rla3_extra_info.matte_type=ReadBlobMSBShort(image); + rla3_extra_info.matte_bits=ReadBlobMSBShort(image); + rla3_extra_info.auxiliary_type=ReadBlobMSBShort(image); + rla3_extra_info.auxiliary_bits=ReadBlobMSBShort(image); + (void) ReadBlob(image,32,(char *) rla3_extra_info.auxiliary); + (void) ReadBlob(image,36,(char *) rla3_extra_info.space); + rla3_extra_info.next=(long) ReadBlobMSBLong(image); + } + else + { + rlb_extra_info.filter_type=ReadBlobMSBShort(image); + rlb_extra_info.magic_number=ReadBlobMSBLong(image); + rlb_extra_info.lut_size=ReadBlobMSBLong(image); + rlb_extra_info.user_space_size=ReadBlobMSBLong(image); + rlb_extra_info.wf_space_size=ReadBlobMSBLong(image); + rlb_extra_info.lut_type=ReadBlobMSBShort(image); + rlb_extra_info.mix_type=ReadBlobMSBShort(image); + rlb_extra_info.encode_type=ReadBlobMSBShort(image); + rlb_extra_info.padding=ReadBlobMSBShort(image); + (void) ReadBlob(image,100,(char *) rlb_extra_info.space); + } + if (EOFBlob(image)) + ThrowReaderException(CorruptImageError,UnexpectedEndOfFile,image); + + /* + Verify revision. + */ + +/* if (rla3_extra_info.revision != 0xFFFE) */ +/* ThrowReaderException(CorruptImageError,ImproperImageHeader,image); */ + + /* + Verify dimensions. + */ + if ((((long) rla_info.active_window.right - rla_info.active_window.left) < 0) || + (((long) rla_info.active_window.top-rla_info.active_window.bottom) < 0)) + ThrowReaderException(CorruptImageError,ImproperImageHeader,image); + + if ((rla_info.storage_type != 0) || (rla_info.storage_type > 3)) + ThrowReaderException(CorruptImageError,ImproperImageHeader,image); + + if (rla_info.storage_type != 0) + ThrowReaderException(CoderError,DataStorageTypeIsNotSupported,image); + + if (LocaleNCompare(rla_info.chan,"rgb",3) != 0) + ThrowReaderException(CoderError,ColorTypeNotSupported,image); + /* Initialize image structure. */ - image->matte=rla_info.number_matte_channels != 0; - image->columns=rla_info.active_window.right-rla_info.active_window.left; - image->rows=rla_info.active_window.top-rla_info.active_window.bottom; + image->matte=(rla_info.number_matte_channels != 0 ? MagickTrue: MagickFalse); + image->columns=rla_info.active_window.right-rla_info.active_window.left+1; + image->rows=rla_info.active_window.top-rla_info.active_window.bottom+1; if (image_info->ping) { CloseBlob(image); return(image); } - scanlines=MagickAllocateMemory(long *,image->rows*sizeof(long)); - if (scanlines == (long *) NULL) + number_channels=rla_info.number_channels+rla_info.number_matte_channels; + scanlines=MagickAllocateMemoryElements(magick_uint32_t *,image->rows,sizeof(magick_uint32_t)); + if (scanlines == (magick_uint32_t *) NULL) ThrowReaderException(ResourceLimitError,MemoryAllocationFailed,image); if (*rla_info.description != '\0') (void) SetImageAttribute(image,"comment",rla_info.description); @@ -251,21 +333,30 @@ Read offsets to each scanline data. */ for (i=0; i < (long) image->rows; i++) - scanlines[i]=(long) ReadBlobMSBLong(image); + scanlines[i]=(magick_uint32_t) ReadBlobMSBLong(image); + if (EOFBlob(image)) + ThrowReaderException(CorruptImageError,UnexpectedEndOfFile,image); /* Read image data. */ x=0; - indexes=(IndexPacket *) NULL; for (y=0; y < (long) image->rows; y++) { - (void) SeekBlob(image,scanlines[image->rows-y-1],SEEK_SET); - for (channel=0; channel < (int) rla_info.number_channels; channel++) + if (SeekBlob(image,scanlines[image->rows-y-1],SEEK_SET) == -1) + { + status=MagickFail; + break; + } + for (channel=0; channel < number_channels; channel++) { length=ReadBlobMSBShort(image); while (length > 0) { - byte=ReadBlobByte(image); + if ((byte=ReadBlobByte(image)) == EOF) + { + status=MagickFail; + break; + } runlength=byte; if (byte > 127) runlength=byte-256; @@ -274,21 +365,26 @@ break; if (runlength < 0) { - q=GetImagePixels(image,(long) (x % image->columns), - (long) (y/image->columns),1,1); - if (q == (PixelPacket *) NULL) - break; - indexes=GetIndexes(image); while (runlength < 0) { - byte=ReadBlobByte(image); + q=GetImagePixels(image,(long) (x % image->columns), + (long) (y % image->columns),1,1); + if (q == (PixelPacket *) NULL) + { + status=MagickFail; + break; + } + if ((byte=ReadBlobByte(image)) == EOF) + { + status=MagickFail; + break; + } length--; switch (channel) { case 0: { q->red=ScaleCharToQuantum(byte); - *indexes=0; break; } case 1: @@ -302,34 +398,47 @@ break; } case 3: - default: { q->opacity=(Quantum) (MaxRGB-ScaleCharToQuantum(byte)); break; } + default: + { + /* Depth channel ? */ + break; + } } if (!SyncImagePixels(image)) - break; + { + status=MagickFail; + break; + } x++; runlength++; } continue; } - byte=ReadBlobByte(image); + if ((byte=ReadBlobByte(image)) == EOF) + { + status=MagickFail; + break; + } length--; runlength++; do { q=GetImagePixels(image,(long) (x % image->columns), - (long) (y/image->columns),1,1); + (long) (y % image->columns),1,1); if (q == (PixelPacket *) NULL) - break; + { + status=MagickFail; + break; + } switch (channel) { case 0: { q->red=ScaleCharToQuantum(byte); - *indexes=0; break; } case 1: @@ -343,27 +452,43 @@ break; } case 3: - default: { q->opacity=(Quantum) (MaxRGB-ScaleCharToQuantum(byte)); break; } + default: + { + /* Depth channel ? */ + break; + } } if (!SyncImagePixels(image)) - break; + { + status=MagickFail; + break; + } x++; runlength--; } while (runlength > 0); + + if (MagickFail == status) + break; } + if (MagickFail == status) + break; } if (QuantumTick(y,image->rows)) if (!MagickMonitor(LoadImageText,y,image->rows,exception)) - break; + { + status=MagickFail; + break; + } + if (MagickFail == status) + break; } if (EOFBlob(image)) - ThrowException(exception,CorruptImageError,UnexpectedEndOfFile, - image->filename); + ThrowReaderException(CorruptImageError,UnexpectedEndOfFile,image); CloseBlob(image); return(image); } only in patch2: unchanged: --- graphicsmagick-1.1.11.orig/coders/avs.c +++ graphicsmagick-1.1.11/coders/avs.c @@ -79,6 +79,8 @@ % % */ +#define AVS_WIDTH_LIMIT 65536 /* Artificially limit width to 64K pixels */ +#define AVS_HEIGHT_LIMIT 65536 /* Artificially limit height to 64K pixels */ static Image *ReadAVSImage(const ImageInfo *image_info,ExceptionInfo *exception) { Image @@ -96,9 +98,6 @@ register unsigned char *p; - size_t - count; - unsigned char *pixels; @@ -118,17 +117,26 @@ assert(exception->signature == MagickSignature); image=AllocateImage(image_info); status=OpenBlob(image_info,image,ReadBinaryBlobMode,exception); - if (status == False) + if (status == MagickFail) ThrowReaderException(FileOpenError,UnableToOpenFile,image); /* Read AVS image. */ width=ReadBlobMSBLong(image); height=ReadBlobMSBLong(image); - if ((width == (unsigned long) ~0) || (height == (unsigned long) ~0)) - ThrowReaderException(CorruptImageError,ImproperImageHeader,image); + if (EOFBlob(image)) + ThrowReaderException(CorruptImageError,UnexpectedEndOfFile,image); + + /* + Impose a maximum width and height limit in order to avoid + incredibly huge allocations. + */ + if ((width > AVS_WIDTH_LIMIT) || (height > AVS_HEIGHT_LIMIT)) + ThrowReaderException(CoderError,ImageColumnOrRowSizeIsNotSupported,image); + do { + size_t row_bytes; /* Convert AVS raster image to pixel packets. */ @@ -138,18 +146,25 @@ if (image_info->ping && (image_info->subrange != 0)) if (image->scene >= (image_info->subimage+image_info->subrange-1)) break; - pixels=MagickAllocateMemory(unsigned char *,4*image->columns); + pixels=MagickAllocateMemoryElements(unsigned char *,image->columns,4); if (pixels == (unsigned char *) NULL) ThrowReaderException(ResourceLimitError,MemoryAllocationFailed,image); + row_bytes=4*image->columns; for (y=0; y < (long) image->rows; y++) { - count=ReadBlob(image,4*image->columns,pixels); - if (count == 0) - ThrowReaderException(CorruptImageError,UnableToReadImageData,image); + if (ReadBlob(image,4*image->columns,pixels) != row_bytes) + { + ThrowException(exception,CorruptImageError,UnexpectedEndOfFile, + image->filename); + status=MagickFail; + } p=pixels; q=SetImagePixels(image,0,y,image->columns,1); if (q == (PixelPacket *) NULL) - break; + { + status=MagickFail; + break; + } for (x=0; x < (long) image->columns; x++) { q->opacity=(Quantum) (MaxRGB-ScaleCharToQuantum(*p++)); @@ -160,19 +175,25 @@ q++; } if (!SyncImagePixels(image)) - break; + { + status=MagickFail; + break; + } if (image->previous == (Image *) NULL) if (QuantumTick(y,image->rows)) if (!MagickMonitor(LoadImageText,y,image->rows,exception)) - break; + { + status=MagickFail; + break; + } + if (MagickFail == status) + break; } MagickFreeMemory(pixels); - if (EOFBlob(image)) - { - ThrowException(exception,CorruptImageError,UnexpectedEndOfFile, - image->filename); - break; - } + + if (MagickFail == status) + break; + /* Proceed to next image. */ @@ -181,7 +202,8 @@ break; width=ReadBlobMSBLong(image); height=ReadBlobMSBLong(image); - if ((width != (unsigned long) ~0) && (height != (unsigned long) ~0)) + if (!(EOFBlob(image)) && (width <= AVS_WIDTH_LIMIT) && + (height <= AVS_HEIGHT_LIMIT)) { /* Allocate next image structure. @@ -195,13 +217,20 @@ image=SyncNextImageInList(image); status=MagickMonitor(LoadImagesText,TellBlob(image),GetBlobSize(image), exception); - if (status == False) + if (status == MagickFail) break; } } while ((width != (unsigned long) ~0) && (height != (unsigned long) ~0)); while (image->previous != (Image *) NULL) image=image->previous; CloseBlob(image); + + if (MagickFail == status) + { + DestroyImageList(image); + image=(Image *) NULL; + } + return(image); } only in patch2: unchanged: --- graphicsmagick-1.1.11.orig/coders/dpx.c +++ graphicsmagick-1.1.11/coders/dpx.c @@ -174,17 +174,22 @@ ThrowReaderException(CorruptImageError,ImproperImageHeader,image); headersize=ReadBlobMSBLong(image); for (i=0; i < 764; i++) - (void) ReadBlobByte(image); + if (ReadBlobByte(image) == EOF) + ThrowReaderException(CorruptImageError,UnexpectedEndOfFile,image); image->columns= ReadBlobMSBLong(image); image->rows= ReadBlobMSBLong(image); for (i=0; i < 20; i++) - (void) ReadBlobByte(image); + if (ReadBlobByte(image) == EOF) + ThrowReaderException(CorruptImageError,UnexpectedEndOfFile,image); colortype=ReadBlobByte(image); - (void) ReadBlobByte(image); - (void) ReadBlobByte(image); + if (ReadBlobByte(image) == EOF) + ThrowReaderException(CorruptImageError,UnexpectedEndOfFile,image); + if (ReadBlobByte(image) == EOF) + ThrowReaderException(CorruptImageError,UnexpectedEndOfFile,image); image->depth=ReadBlobByte(image) > 8 ? 16 : 8; for (i=0; i < (long) (headersize-804); i++) - (void) ReadBlobByte(image); + if (ReadBlobByte(image) == EOF) + ThrowReaderException(CorruptImageError,UnexpectedEndOfFile,image); if (image_info->ping) { CloseBlob(image); only in patch2: unchanged: --- graphicsmagick-1.1.11.orig/coders/avi.c +++ graphicsmagick-1.1.11/coders/avi.c @@ -137,7 +137,7 @@ % % */ -static unsigned int DecodeImage(Image *image,const unsigned int compression, +static MagickPassFail DecodeImage(Image *image,const unsigned int compression, unsigned char *pixels) { long @@ -164,16 +164,16 @@ { if (q < pixels || q >= end) break; - count=ReadBlobByte(image); - if (count == EOF) - break; + if ((count=ReadBlobByte(image)) == EOF) + goto unexpected_eof; if (count != 0) { count=Min(count, end - q); /* Encoded mode. */ - byte=ReadBlobByte(image); + if ((byte=ReadBlobByte(image)) == EOF) + goto unexpected_eof; for (i=0; i < count; i++) { if (compression == 1) @@ -189,9 +189,10 @@ /* Escape mode. */ - count=ReadBlobByte(image); + if ((count=ReadBlobByte(image)) == EOF) + goto unexpected_eof; if (count == 0x01) - return(True); + return(MagickPass); switch (count) { case 0x00: @@ -209,8 +210,17 @@ /* Delta mode. */ - x+=ReadBlobByte(image); - y+=ReadBlobByte(image); + if ((byte=ReadBlobByte(image)) == EOF) + goto unexpected_eof; + x+=byte; + if ((byte=ReadBlobByte(image)) == EOF) + goto unexpected_eof; + y+=byte; + if ((x >= (long) image->columns) || (y >= (long) image->rows)) + { + ThrowException(&image->exception,CorruptImageError,CorruptImage,NULL); + return MagickFail; + } q=pixels+y*image->columns+x; break; } @@ -223,11 +233,18 @@ for (i=0; i < count; i++) { if (compression == 1) - *q++=ReadBlobByte(image); + { + if ((byte=ReadBlobByte(image)) == EOF) + goto unexpected_eof; + *q++=byte; + } else { if ((i & 0x01) == 0) - byte=ReadBlobByte(image); + { + if ((byte=ReadBlobByte(image)) == EOF) + goto unexpected_eof; + } *q++=(unsigned char) ((i & 0x01) ? (byte & 0x0f) : ((byte >> 4) & 0x0f)); } @@ -239,11 +256,17 @@ if (compression == 1) { if (count & 0x01) - (void) ReadBlobByte(image); + { + if (ReadBlobByte(image) == EOF) + goto unexpected_eof; + } } else if (((count & 0x03) == 1) || ((count & 0x03) == 2)) - (void) ReadBlobByte(image); + { + if (ReadBlobByte(image) == EOF) + goto unexpected_eof; + } break; } } @@ -252,9 +275,15 @@ if (!MagickMonitor(LoadImageText,y,image->rows,&image->exception)) break; } - (void) ReadBlobByte(image); /* end of line */ - (void) ReadBlobByte(image); - return(True); + if (ReadBlobByte(image) == EOF) /* end of line */ + goto unexpected_eof; + if (ReadBlobByte(image) == EOF) + goto unexpected_eof; + return(MagickPass); + + unexpected_eof: + ThrowException(&image->exception,CorruptImageError,UnexpectedEndOfFile,NULL); + return MagickFail; } /* @@ -381,6 +410,9 @@ count, number_colors; + MagickBool + first_chunk; + /* Open image file. */ @@ -396,13 +428,22 @@ (void) memset(&bmp_info,0,sizeof(BMPInfo)); colormap=(PixelPacket *) NULL; number_colors=0; + first_chunk=MagickTrue; for ( ; ; ) { count=ReadBlob(image,4,id); - if (count == 0) - break; + if (count != 4) + ThrowReaderException(CorruptImageError,UnexpectedEndOfFile,image); id[4]='\0'; + if (first_chunk) + { + if (memcmp(id,"RIFF",4) != 0) + ThrowReaderException(CorruptImageError,ImproperImageHeader,image); + first_chunk=MagickFalse; + } chunk_size=ReadBlobLSBLong(image); + if (EOFBlob(image)) + ThrowReaderException(CorruptImageError,UnexpectedEndOfFile,image); if (chunk_size == 0) break; if (chunk_size & 0x01) @@ -420,7 +461,8 @@ bmp_info.compression); ThrowException2(exception,CorruptImageError,message,image->filename); for ( ; chunk_size != 0; chunk_size--) - (void) ReadBlobByte(image); + if (ReadBlobByte(image) == EOF) + ThrowReaderException(CorruptImageError,UnexpectedEndOfFile,image); continue; } /* @@ -448,11 +490,18 @@ ThrowReaderException(ResourceLimitError,MemoryAllocationFailed, image); if (LocaleCompare(id,"00db") == 0) - (void) ReadBlob(image,bytes_per_line*image->rows,(char *) pixels); + { + size_t + size; + + size=bytes_per_line*image->rows; + if (ReadBlob(image,bytes_per_line*image->rows,(char *) pixels) != size) + ThrowReaderException(CorruptImageError,UnexpectedEndOfFile,image); + } else { status=DecodeImage(image,1,pixels); - if (status == False) + if (status == MagickFail) ThrowReaderException(CorruptImageError,UnableToRunlengthDecodeImage,image); } /* @@ -704,18 +753,22 @@ avi_info.data_rate=ReadBlobLSBLong(image); avi_info.start_time=ReadBlobLSBLong(image); avi_info.data_length=ReadBlobLSBLong(image); + if (EOFBlob(image)) + ThrowReaderException(CorruptImageError,UnexpectedEndOfFile,image); continue; } if (LocaleCompare(id,"idx1") == 0) { for ( ; chunk_size != 0; chunk_size--) - (void) ReadBlobByte(image); + if (ReadBlobByte(image) == EOF) + ThrowReaderException(CorruptImageError,UnexpectedEndOfFile,image); continue; } if (LocaleCompare(id,"JUNK") == 0) { for ( ; chunk_size != 0; chunk_size--) - (void) ReadBlobByte(image); + if (ReadBlobByte(image) == EOF) + ThrowReaderException(CorruptImageError,UnexpectedEndOfFile,image); continue; } if (LocaleCompare(id,"LIST") == 0) @@ -723,7 +776,8 @@ /* List of chunks. */ - (void) ReadBlob(image,4,id); + if (ReadBlob(image,4,id) != 4) + ThrowReaderException(CorruptImageError,UnexpectedEndOfFile,image); if (image_info->verbose) (void) fprintf(stdout," List type %.1024s\n",id); continue; @@ -733,7 +787,8 @@ /* File header. */ - (void) ReadBlob(image,4,id); + if (ReadBlob(image,4,id) != 4) + ThrowReaderException(CorruptImageError,UnexpectedEndOfFile,image); if (image_info->verbose) (void) fprintf(stdout," RIFF form type %.1024s\n",id); continue; @@ -752,13 +807,16 @@ bmp_info.height=ReadBlobLSBLong(image); bmp_info.planes=ReadBlobLSBShort(image); bmp_info.bits_per_pixel=ReadBlobLSBShort(image); - (void) ReadBlob(image,4,bmp_info.compression); + if (ReadBlob(image,4,bmp_info.compression) != 4) + ThrowReaderException(CorruptImageError,UnexpectedEndOfFile,image); bmp_info.compression[4]='\0'; bmp_info.image_size=ReadBlobLSBLong(image); bmp_info.x_pixels=ReadBlobLSBLong(image); bmp_info.y_pixels=ReadBlobLSBLong(image); bmp_info.number_colors=ReadBlobLSBLong(image); bmp_info.important_colors=ReadBlobLSBLong(image); + if (EOFBlob(image)) + ThrowReaderException(CorruptImageError,UnexpectedEndOfFile,image); chunk_size-=40; number_colors=bmp_info.number_colors; if ((number_colors == 0) && (bmp_info.bits_per_pixel <= 8)) @@ -774,28 +832,33 @@ colormap[i].blue=ScaleCharToQuantum(ReadBlobByte(image)); colormap[i].green=ScaleCharToQuantum(ReadBlobByte(image)); colormap[i].red=ScaleCharToQuantum(ReadBlobByte(image)); - (void) ReadBlobByte(image); + if (ReadBlobByte(image) == EOF) + ThrowReaderException(CorruptImageError,UnexpectedEndOfFile,image); chunk_size-=4; } } for ( ; chunk_size != 0; chunk_size--) - (void) ReadBlobByte(image); + if (ReadBlobByte(image) == EOF) + ThrowReaderException(CorruptImageError,UnexpectedEndOfFile,image); if (image_info->verbose) (void) fprintf(stdout,"Video compression: %.1024s\n", bmp_info.compression); continue; } for ( ; chunk_size != 0; chunk_size--) - (void) ReadBlobByte(image); + if (ReadBlobByte(image) == EOF) + ThrowReaderException(CorruptImageError,UnexpectedEndOfFile,image); continue; } if (LocaleCompare(id,"strh") == 0) { if (image_info->verbose) (void) fprintf(stdout," Stream header\n"); - (void) ReadBlob(image,4,stream_info.data_type); + if (ReadBlob(image,4,stream_info.data_type) != 4) + ThrowReaderException(CorruptImageError,UnexpectedEndOfFile,image); stream_info.data_type[4]='\0'; - (void) ReadBlob(image,4,stream_info.data_handler); + if (ReadBlob(image,4,stream_info.data_handler) != 4) + ThrowReaderException(CorruptImageError,UnexpectedEndOfFile,image); stream_info.data_handler[4]='\0'; stream_info.flags=ReadBlobLSBLong(image); stream_info.priority=ReadBlobLSBLong(image); @@ -807,10 +870,13 @@ stream_info.buffer_size=ReadBlobLSBLong(image); stream_info.quality=ReadBlobLSBLong(image); stream_info.sample_size=ReadBlobLSBLong(image); + if (EOFBlob(image)) + ThrowReaderException(CorruptImageError,UnexpectedEndOfFile,image); if (chunk_size & 0x01) chunk_size++; for (chunk_size-=48; chunk_size != 0; chunk_size--) - (void) ReadBlobByte(image); + if (ReadBlobByte(image) == EOF) + ThrowReaderException(CorruptImageError,UnexpectedEndOfFile,image); if (image_info->verbose) (void) fprintf(stdout,"AVI Test handler: %.1024s\n", stream_info.data_handler); @@ -819,19 +885,22 @@ if (LocaleCompare(id,"strn") == 0) { for ( ; chunk_size != 0; chunk_size--) - (void) ReadBlobByte(image); + if (ReadBlobByte(image) == EOF) + ThrowReaderException(CorruptImageError,UnexpectedEndOfFile,image); continue; } if (LocaleCompare(id,"vedt") == 0) { for ( ; chunk_size != 0; chunk_size--) - (void) ReadBlobByte(image); + if (ReadBlobByte(image) == EOF) + ThrowReaderException(CorruptImageError,UnexpectedEndOfFile,image); continue; } FormatString(message,"AVI chunk %.1024s not yet supported",id); ThrowException2(exception,CorruptImageError,message,image->filename); for ( ; chunk_size != 0; chunk_size--) - (void) ReadBlobByte(image); + if (ReadBlobByte(image) == EOF) + ThrowReaderException(CorruptImageError,UnexpectedEndOfFile,image); continue; } while (image->previous != (Image *) NULL) only in patch2: unchanged: --- graphicsmagick-1.1.11.orig/coders/cineon.c +++ graphicsmagick-1.1.11/coders/cineon.c @@ -607,14 +607,29 @@ unsigned char *user_data; + const size_t + block_size = 65536UL; + size_t + read_size, user_data_length; - - user_data_length=cin_file_info.user_defined_length; - user_data=MagickAllocateMemory(unsigned char *,user_data_length); - if (user_data == (unsigned char *) NULL) - ThrowReaderException(ResourceLimitError,MemoryAllocationFailed,image); - offset += ReadBlob(image,user_data_length,user_data); + + user_data_length=0UL; + user_data=(unsigned char *) NULL; + while (user_data_length < cin_file_info.user_defined_length) + { + read_size=Min(block_size,cin_file_info.user_defined_length-user_data_length); + MagickReallocMemory(user_data,user_data_length+read_size); + if (user_data == (unsigned char *) NULL) + ThrowReaderException(ResourceLimitError,MemoryAllocationFailed,image); + if (ReadBlob(image,read_size,user_data+user_data_length) != read_size) + { + MagickFreeMemory(user_data); + ThrowReaderException(CorruptImageError,UnexpectedEndOfFile,image); + } + user_data_length += read_size; + offset += read_size; + } if (!SetImageProfile(image,"CINEONUSERDATA",user_data,user_data_length)) { MagickFreeMemory(user_data); @@ -633,7 +648,8 @@ Read remainder of header. */ for ( ; offset < pixels_offset ; offset++ ) - (void) ReadBlobByte(image); + if (ReadBlobByte(image) == EOF) + ThrowReaderException(CorruptImageError,UnexpectedEndOfFile,image); if (image->logging) (void) LogMagickEvent(CoderEvent,GetMagickModule(), only in patch2: unchanged: --- graphicsmagick-1.1.11.orig/coders/mtv.c +++ graphicsmagick-1.1.11/coders/mtv.c @@ -125,11 +125,16 @@ Read MTV image. */ (void) ReadBlobString(image,buffer); + columns=0; + rows=0; count=sscanf(buffer,"%lu %lu\n",&columns,&rows); - if (count <= 0) + if (count != 2) ThrowReaderException(CorruptImageError,ImproperImageHeader,image); do { + size_t + row_size; + /* Initialize image structure. */ @@ -142,15 +147,14 @@ /* Convert MTV raster image to pixel packets. */ - pixels=MagickAllocateMemory(unsigned char *,3*image->columns); + pixels=MagickAllocateMemoryElements(unsigned char *,image->columns,3); if (pixels == (unsigned char *) NULL) ThrowReaderException(ResourceLimitError,MemoryAllocationFailed,image); + row_size=image->columns*3; for (y=0; y < (long) image->rows; y++) { - count=(long) ReadBlob(image,3*image->columns,pixels); - if (count == 0) - ThrowReaderException(CorruptImageError,UnableToReadImageData, - image); + if (ReadBlob(image,row_size,pixels) != row_size) + ThrowReaderException(CorruptImageError,UnexpectedEndOfFile,image); p=pixels; q=SetImagePixels(image,0,y,image->columns,1); if (q == (PixelPacket *) NULL) @@ -185,7 +189,7 @@ *buffer='\0'; (void) ReadBlobString(image,buffer); count=sscanf(buffer,"%lu %lu\n",&columns,&rows); - if (count > 0) + if (count == 2) { /* Allocate next image structure. @@ -200,7 +204,7 @@ if (!MagickMonitor(LoadImagesText,TellBlob(image),GetBlobSize(image),exception)) break; } - } while (count > 0); + } while (count == 2); while (image->previous != (Image *) NULL) image=image->previous; CloseBlob(image); only in patch2: unchanged: --- graphicsmagick-1.1.11.orig/magick/utility.h +++ graphicsmagick-1.1.11/magick/utility.h @@ -122,6 +122,7 @@ extern MagickExport void *AcquireMemory(const size_t), + *AcquireQuantumMemory(const size_t,const size_t), *MagickAcquireMemoryArray(const size_t count,const size_t size), AppendImageFormat(const char *,char *), *CloneMemory(void *,const void *,const size_t), only in patch2: unchanged: --- graphicsmagick-1.1.11.orig/magick/xwindow.c +++ graphicsmagick-1.1.11/magick/xwindow.c @@ -5384,6 +5384,9 @@ const XResourceInfo *resource_info,XWindowInfo *window,Image *image, unsigned int width,unsigned int height) { +#define CheckOverflowException(length,width,height) \ + (((height) != 0) && ((length)/((size_t) height) != ((size_t) width))) + int depth, format; @@ -5485,9 +5488,12 @@ &segment_info[1],width,height); window->shared_memory&=(ximage != (XImage *) NULL); + length=(size_t) ximage->bytes_per_line*ximage->height; + if (CheckOverflowException(length,ximage->bytes_per_line,ximage->height)) + window->shared_memory=MagickFalse; + if (window->shared_memory) - segment_info[1].shmid=shmget(IPC_PRIVATE,(size_t) - (ximage->bytes_per_line*ximage->height),IPC_CREAT | 0777); + segment_info[1].shmid=shmget(IPC_PRIVATE,length,IPC_CREAT | 0777); window->shared_memory&=(segment_info[1].shmid >= 0); if (window->shared_memory) @@ -5596,12 +5602,12 @@ } if (!window->shared_memory) { - if (ximage->format == XYBitmap) - ximage->data=MagickAllocateMemory(char *, - ximage->bytes_per_line*ximage->height*ximage->depth); + if (ximage->format != XYBitmap) + ximage->data=(char *) AcquireQuantumMemory((size_t) + ximage->bytes_per_line,(size_t) ximage->height); else - ximage->data=MagickAllocateMemory(char *, - ximage->bytes_per_line*ximage->height); + ximage->data=(char *) AcquireQuantumMemory((size_t) + ximage->bytes_per_line*ximage->depth,(size_t) ximage->height); } if (ximage->data == (char *) NULL) { @@ -5677,9 +5683,9 @@ /* Allocate matte image pixel data. */ - length=matte_image->bytes_per_line* - matte_image->height*matte_image->depth; - matte_image->data=MagickAllocateMemory(char *,length); + matte_image->data=(char *) AcquireQuantumMemory((size_t) + matte_image->bytes_per_line*matte_image->depth, + (size_t) matte_image->height); if (matte_image->data == (char *) NULL) { XDestroyImage(matte_image); only in patch2: unchanged: --- graphicsmagick-1.1.11.orig/magick/memory.c +++ graphicsmagick-1.1.11/magick/memory.c @@ -188,6 +188,48 @@ MagickFreeMemory(*memory); } + +/* +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +% % +% % +% % +% A c q u i r e Q u a n t u m M e m o r y % +% % +% % +% % +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +% +% AcquireQuantumMemory() returns a pointer to a block of memory at least +% count * quantum bytes suitably aligned for any use. +% +% The format of the AcquireQuantumMemory method is: +% +% void *AcquireQuantumMemory(const size_t count,const size_t quantum) +% +% A description of each parameter follows: +% +% o count: The number of quantum elements to allocate. +% +% o quantum: The number of bytes in each quantum. +% +*/ +MagickExport void *AcquireQuantumMemory(const size_t count,const size_t quantum) +{ + size_t + size; + + size=count*quantum; + if ((count == 0) || (quantum != (size/count))) + { + errno=ENOMEM; + return((void *) NULL); + } + return(AcquireMemory(size)); +} + + + /* %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % %