File ImageMagick-6.2.5-bug258253.patch of Package ImageMagick
--- coders/bmp.c
+++ coders/bmp.c
@@ -842,7 +842,8 @@
packet_size=3;
else
packet_size=4;
- (void) SeekBlob(image,start_position+14+bmp_info.size,SEEK_SET);
+ if (SeekBlob(image,start_position+14+bmp_info.size,SEEK_SET) == -1)
+ ThrowReaderException(CorruptImageError,"ImproperImageHeader")
count=ReadBlob(image,packet_size*image->colors,bmp_colormap);
if (count != (ssize_t) (packet_size*image->colors))
ThrowReaderException(CorruptImageError,"InsufficientImageDataInFile");
@@ -863,7 +864,8 @@
/*
Read image data.
*/
- (void) SeekBlob(image,start_position+bmp_info.offset_bits,SEEK_SET);
+ if (SeekBlob(image,start_position+bmp_info.offset_bits,SEEK_SET) == -1)
+ ThrowReaderException(CorruptImageError,"ImproperImageHeader")
if (bmp_info.compression == BI_RLE4)
bmp_info.bits_per_pixel<<=1;
bytes_per_line=4*((image->columns*bmp_info.bits_per_pixel+31)/32);
@@ -1282,7 +1284,8 @@
break;
*magick='\0';
if (bmp_info.ba_offset != 0)
- (void) SeekBlob(image,(MagickOffsetType) bmp_info.ba_offset,SEEK_SET);
+ if (SeekBlob(image,(MagickOffsetType) bmp_info.ba_offset,SEEK_SET) == -1)
+ ThrowReaderException(CorruptImageError,"ImproperImageHeader")
count=ReadBlob(image,2,magick);
if ((count == 2) && (IsBMP(magick,2) != MagickFalse))
{
--- coders/cin.c
+++ coders/cin.c
@@ -297,7 +297,8 @@
(void) ReadBlobByte(image);
image->columns=ReadBlobLong(image);
image->rows=ReadBlobLong(image);
- (void) SeekBlob(image,(MagickOffsetType) headersize,SEEK_SET);
+ if (SeekBlob(image,(MagickOffsetType) headersize,SEEK_SET) == -1)
+ ThrowReaderException(CorruptImageError,"ImproperImageHeader");
if (image_info->ping)
{
CloseBlob(image);
--- coders/dcm.c
+++ coders/dcm.c
@@ -2900,6 +2900,9 @@
else
if ((quantum != 0) && (length != 0))
{
+ /* new check for CVE-2007-1797 */
+ if (length > ((~0UL)/quantum))
+ ThrowReaderException(CorruptImageError,"ImproperImageHeader");
data=(unsigned char *)
AcquireMagickMemory((size_t) quantum*(length+1));
if (data == (unsigned char *) NULL)
--- coders/icon.c
+++ coders/icon.c
@@ -242,13 +242,16 @@
/*
Verify Icon identifier.
*/
- (void) SeekBlob(image,(MagickOffsetType) icon_file.directory[i].offset,
- SEEK_SET);
+ if (SeekBlob(image,(MagickOffsetType) icon_file.directory[i].offset,
+ SEEK_SET) == -1)
+ ThrowReaderException(CorruptImageError,"ImproperImageHeader");
icon_info.size=ReadBlobLSBLong(image);
icon_info.width=ReadBlobLSBLong(image);
icon_info.height=ReadBlobLSBLong(image);
icon_info.planes=ReadBlobLSBShort(image);
icon_info.bits_per_pixel=ReadBlobLSBShort(image);
+ if (icon_info.bits_per_pixel > 32)
+ ThrowReaderException(CorruptImageError,"ImproperImageHeader");
icon_info.compression=ReadBlobLSBLong(image);
icon_info.image_size=ReadBlobLSBLong(image);
icon_info.x_pixels=ReadBlobLSBLong(image);
@@ -259,7 +262,7 @@
image->columns=icon_info.width;
image->rows=icon_info.height;
image->depth=8;
- if ((icon_info.number_colors != 0) || (icon_info.bits_per_pixel < 16))
+ if ((icon_info.number_colors != 0) || (icon_info.bits_per_pixel <= 16))
{
image->storage_class=PseudoClass;
image->colors=icon_info.number_colors;
--- coders/pcx.c
+++ coders/pcx.c
@@ -289,7 +289,9 @@
}
}
if (page_table != (MagickOffsetType *) NULL)
- (void) SeekBlob(image,(MagickOffsetType) page_table[0],SEEK_SET);
+ if (SeekBlob(image,(MagickOffsetType) page_table[0],SEEK_SET)
+ == -1)
+ ThrowReaderException(CorruptImageError,"ImproperImageHeader");
pcx_colormap=(unsigned char *) NULL;
count=ReadBlob(image,1,&pcx_info.identifier);
for (id=1; id < 1024; id++)
@@ -328,7 +330,11 @@
if ((pcx_info.bits_per_pixel != 8) || (pcx_info.planes == 1))
if ((pcx_info.version == 3) || (pcx_info.version == 5) ||
((pcx_info.bits_per_pixel*pcx_info.planes) == 1))
- image->colors=1 << (pcx_info.bits_per_pixel*pcx_info.planes);
+ {
+ image->colors=1 << (pcx_info.bits_per_pixel*pcx_info.planes);
+ if (image->colors > 256)
+ image->colors = 256;
+ }
if (AllocateImageColormap(image,image->colors) == MagickFalse)
ThrowReaderException(ResourceLimitError,"MemoryAllocationFailed");
if ((pcx_info.bits_per_pixel >= 8) && (pcx_info.planes != 1))
@@ -355,7 +361,7 @@
pcx_pixels=(unsigned char *)
AcquireMagickMemory(pcx_packets*sizeof(*pcx_pixels));
scanline=(unsigned char *) AcquireMagickMemory(Max(image->columns,
- pcx_info.bytes_per_line)*pcx_info.planes*sizeof(*scanline));
+ pcx_info.bytes_per_line)*Max(pcx_info.planes,8)*sizeof(*scanline));
if ((pcx_pixels == (unsigned char *) NULL) ||
(scanline == (unsigned char *) NULL))
ThrowReaderException(ResourceLimitError,"MemoryAllocationFailed");
@@ -613,7 +619,9 @@
break;
if (page_table[id] == 0)
break;
- (void) SeekBlob(image,(MagickOffsetType) page_table[id],SEEK_SET);
+ if (SeekBlob(image,(MagickOffsetType) page_table[id],SEEK_SET)
+ == -1)
+ ThrowReaderException(CorruptImageError,"ImproperImageHeader");
count=ReadBlob(image,1,&pcx_info.identifier);
if ((count != 0) && (pcx_info.identifier == 0x0a))
{
--- coders/pict.c
+++ coders/pict.c
@@ -79,6 +79,10 @@
pixmap.plane_bytes=ReadBlobMSBLong(image); \
pixmap.table=ReadBlobMSBLong(image); \
pixmap.reserved=ReadBlobMSBLong(image); \
+ if (pixmap.bits_per_pixel <= 0 || pixmap.bits_per_pixel > 32 || \
+ pixmap.component_count <= 0 || pixmap.component_count > 4 || \
+ pixmap.component_size <= 0) \
+ ThrowReaderException(CorruptImageError,"ImproperImageHeader"); \
}
#define ReadRectangle(rectangle) \
@@ -87,6 +91,9 @@
rectangle.left=ReadBlobMSBShort(image); \
rectangle.bottom=ReadBlobMSBShort(image); \
rectangle.right=ReadBlobMSBShort(image); \
+ if (rectangle.top > rectangle.bottom || \
+ rectangle.left > rectangle.right) \
+ ThrowReaderException(CorruptImageError,"ImproperImageHeader"); \
}
typedef struct _PICTCode
--- coders/png.c
+++ coders/png.c
@@ -4721,6 +4721,8 @@
continue;
}
#ifdef MNG_INSERT_LAYERS
+ if (length < 8)
+ ThrowReaderException(CorruptImageError,"ImproperImageHeader");
image_width=(unsigned long) mng_get_long(p);
image_height=(unsigned long) mng_get_long(&p[4]);
#endif
--- coders/pnm.c
+++ coders/pnm.c
@@ -217,6 +217,19 @@
return(value);
}
+#define ValidateScalingIndex(image, index, max) \
+ do { \
+ if (index < 0 || index > max) \
+ ThrowReaderException(CorruptImageError,"CorruptImage"); \
+ } while (0)
+
+#define ValidateScalingPixel(image, pixel, max) \
+ do { \
+ ValidateScalingIndex(image, pixel.red, max); \
+ ValidateScalingIndex(image, pixel.green, max); \
+ ValidateScalingIndex(image, pixel.blue, max); \
+ } while (0)
+
static Image *ReadPNMImage(const ImageInfo *image_info,ExceptionInfo *exception)
{
#define PushCharPixel(pixel,p) \
@@ -477,6 +490,7 @@
for (x=0; x < (long) image->columns; x++)
{
intensity=PNMInteger(image,10);
+ ValidateScalingIndex(image, intensity, max_value);
if (scale != (Quantum *) NULL)
intensity=scale[intensity];
index=(IndexPacket) intensity;
@@ -522,6 +536,7 @@
pixel.red=PNMInteger(image,10);
pixel.green=PNMInteger(image,10);
pixel.blue=PNMInteger(image,10);
+ ValidateScalingPixel(image, pixel, max_value);
if (scale != (Quantum *) NULL)
{
pixel.red=scale[pixel.red];
@@ -687,6 +702,7 @@
PushCharPixel(pixel.red,p);
PushCharPixel(pixel.green,p);
PushCharPixel(pixel.blue,p);
+ ValidateScalingPixel(image, pixel, max_value);
if (scale != (Quantum *) NULL)
{
pixel.red=scale[pixel.red];
@@ -704,6 +720,7 @@
PushShortPixel(pixel.red,p);
PushShortPixel(pixel.green,p);
PushShortPixel(pixel.blue,p);
+ ValidateScalingPixel(image, pixel, max_value);
if (scale != (Quantum *) NULL)
{
pixel.red=scale[pixel.red];
--- coders/sgi.c
+++ coders/sgi.c
@@ -152,8 +152,9 @@
%
*/
-static void SGIDecode(const unsigned long width,const size_t bytes_per_pixel,
- unsigned char *max_packets,unsigned char *pixels)
+static int SGIDecode(const unsigned long width,const size_t bytes_per_pixel,
+ unsigned char *max_packets,unsigned char *pixels,
+ unsigned long npackets,unsigned long npixels)
{
register unsigned char
*p,
@@ -174,21 +175,30 @@
{
for ( i=0 ; ; )
{
+ if (npackets-- == 0)
+ return -1;
pixel=(unsigned long) (*p++) << 8;
pixel|=(*p++);
count=(ssize_t) (pixel & 0x7f);
i+=count;
if (count == 0 || i > (long) width)
break;
+ if (count > npixels)
+ return -1;
+ npixels -= count;
if ((pixel & 0x80) != 0)
for ( ; count != 0; count--)
{
+ if (npackets-- == 0)
+ return -1;
*q=(*p++);
*(q+1)=(*p++);
q+=8;
}
else
{
+ if (npackets-- == 0)
+ return -1;
pixel=(unsigned long) (*p++) << 8;
pixel|=(*p++);
for ( ; count != 0; count--)
@@ -199,23 +209,32 @@
}
}
}
- return;
+ return 0;
}
for ( i=0 ; ; )
{
+ if (npackets-- == 0)
+ return -1;
pixel=(unsigned long) (*p++);
count=(ssize_t) (pixel & 0x7f);
i+=count;
if (count == 0 || i > (long) width)
break;
+ if (count > npixels)
+ return -1;
+ npixels -= count;
if ((pixel & 0x80) != 0)
for ( ; count != 0; count--)
{
+ if (npackets-- == 0)
+ return -1;
*q=(*p++);
q+=4;
}
else
{
+ if (npackets-- == 0)
+ return -1;
pixel=(unsigned long) (*p++);
for ( ; count != 0; count--)
{
@@ -224,6 +243,7 @@
}
}
}
+ return 0;
}
static Image *ReadSGIImage(const ImageInfo *image_info,ExceptionInfo *exception)
@@ -298,13 +318,12 @@
if ((int) iris_info.storage == 0x01)
image->compression=RLECompression;
iris_info.bytes_per_pixel=(unsigned char) ReadBlobByte(image);
+ if (iris_info.bytes_per_pixel > 2 || iris_info.bytes_per_pixel == 0)
+ ThrowReaderException(CorruptImageError,"ImproperImageHeader");
iris_info.dimension=ReadBlobMSBShort(image);
iris_info.columns=ReadBlobMSBShort(image);
iris_info.rows=ReadBlobMSBShort(image);
iris_info.depth=ReadBlobMSBShort(image);
- image->columns=iris_info.columns;
- image->rows=iris_info.rows;
- image->depth=(unsigned long) (iris_info.depth <= 8 ? 8 : QuantumDepth);
if (iris_info.depth > 4 || iris_info.depth == 0)
ThrowReaderException(CorruptImageError,"ImproperImageHeader");
if (iris_info.depth < 3)
@@ -312,6 +333,9 @@
image->storage_class=PseudoClass;
image->colors=256;
}
+ image->columns=iris_info.columns;
+ image->rows=iris_info.rows;
+ image->depth=bytes_per_pixel == 1 ? 8 : QuantumDepth;
if ((image_info->ping != MagickFalse) && (image_info->number_scenes != 0))
if (image->scene >= (image_info->scene+image_info->number_scenes-1))
break;
@@ -435,8 +459,11 @@
if (EOFBlob(image) != MagickFalse)
break;
offset+=runlength[y+z*iris_info.rows];
- SGIDecode(iris_info.columns,bytes_per_pixel,max_packets,
- p+bytes_per_pixel*z);
+ if (SGIDecode(iris_info.columns,bytes_per_pixel,max_packets,
+ p+bytes_per_pixel*z,
+ runlength[y+z*iris_info.rows]/bytes_per_pixel,
+ iris_info.columns) == -1)
+ ThrowReaderException(CorruptImageError,"ImproperImageHeader");
p+=(iris_info.columns*4*bytes_per_pixel);
}
}
@@ -462,8 +489,11 @@
if (EOFBlob(image) != MagickFalse)
break;
offset+=runlength[y+z*iris_info.rows];
- SGIDecode(iris_info.columns,bytes_per_pixel,max_packets,
- p+bytes_per_pixel*z);
+ if (SGIDecode(iris_info.columns,bytes_per_pixel,max_packets,
+ p+bytes_per_pixel*z,
+ runlength[y+z*iris_info.rows]/bytes_per_pixel,
+ iris_info.columns) == -1)
+ ThrowReaderException(CorruptImageError,"ImproperImageHeader");
}
p+=(iris_info.columns*4*bytes_per_pixel);
}
--- coders/sun.c
+++ coders/sun.c
@@ -304,6 +304,8 @@
sun_info.maplength=ReadBlobMSBLong(image);
image->columns= sun_info.width;
image->rows= sun_info.height;
+ if (sun_info.depth == 0 || sun_info.depth > 32)
+ ThrowReaderException(CorruptImageError,"ImproperImageHeader");
image->depth=sun_info.depth <= 8 ? 8UL : QuantumDepth;
if (sun_info.depth < 24)
{
@@ -462,72 +464,85 @@
}
else
if (image->storage_class == PseudoClass)
- for (y=0; y < (long) image->rows; y++)
{
- q=SetImagePixels(image,0,y,image->columns,1);
- if (q == (PixelPacket *) NULL)
- break;
- indexes=GetIndexes(image);
- for (x=0; x < (long) image->columns; x++)
- indexes[x]=(*p++);
- if ((image->columns % 2) != 0)
- p++;
- if (SyncImagePixels(image) == MagickFalse)
- break;
- if (image->previous == (Image *) NULL)
- if ((image->progress_monitor != (MagickProgressMonitor) NULL) &&
+ unsigned long n = image->rows*(image->columns+image->columns%2);
+ if ((sun_info.type == RT_ENCODED && n > bytes_per_line*image->rows) ||
+ (sun_info.type != RT_ENCODED && n > sun_info.length))
+ ThrowReaderException(CorruptImageError,"ImproperImageHeader");
+ for (y=0; y < (long) image->rows; y++)
+ {
+ q=SetImagePixels(image,0,y,image->columns,1);
+ if (q == (PixelPacket *) NULL)
+ break;
+ indexes=GetIndexes(image);
+ for (x=0; x < (long) image->columns; x++)
+ indexes[x]=(*p++);
+ if ((image->columns % 2) != 0)
+ p++;
+ if (SyncImagePixels(image) == MagickFalse)
+ break;
+ if (image->previous == (Image *) NULL)
+ if ((image->progress_monitor != (MagickProgressMonitor) NULL) &&
(QuantumTick(y,image->rows) != MagickFalse))
- {
+ {
status=image->progress_monitor(LoadImageTag,y,image->rows,
image->client_data);
- if (status == MagickFalse)
+ if (status == MagickFalse)
break;
}
- }
+ }
+ }
else
- for (y=0; y < (long) image->rows; y++)
{
- q=SetImagePixels(image,0,y,image->columns,1);
- if (q == (PixelPacket *) NULL)
- break;
- for (x=0; x < (long) image->columns; x++)
+ unsigned long n = image->columns*((image->matte) ? 4 : 3);
+ n = image->rows*(n+image->columns%2);
+ if ((sun_info.type == RT_ENCODED && n > bytes_per_line*image->rows) ||
+ (sun_info.type != RT_ENCODED && n > sun_info.length))
+ ThrowReaderException(CorruptImageError,"ImproperImageHeader");
+ for (y=0; y < (long) image->rows; y++)
{
- if (image->matte != MagickFalse)
- q->opacity=(Quantum) (QuantumRange-ScaleCharToQuantum(*p++));
- if (sun_info.type == RT_STANDARD)
- {
- q->blue=ScaleCharToQuantum(*p++);
- q->green=ScaleCharToQuantum(*p++);
- q->red=ScaleCharToQuantum(*p++);
- }
- else
- {
- q->red=ScaleCharToQuantum(*p++);
- q->green=ScaleCharToQuantum(*p++);
- q->blue=ScaleCharToQuantum(*p++);
- }
- if (image->colors != 0)
- {
- q->red=image->colormap[q->red].red;
- q->green=image->colormap[q->green].green;
- q->blue=image->colormap[q->blue].blue;
- }
- q++;
- }
- if ((image->columns % 2) != 0)
- p++;
- if (SyncImagePixels(image) == MagickFalse)
- break;
- if (image->previous == (Image *) NULL)
- if ((image->progress_monitor != (MagickProgressMonitor) NULL) &&
+ q=SetImagePixels(image,0,y,image->columns,1);
+ if (q == (PixelPacket *) NULL)
+ break;
+ for (x=0; x < (long) image->columns; x++)
+ {
+ if (image->matte != MagickFalse)
+ q->opacity=(Quantum) (QuantumRange-ScaleCharToQuantum(*p++));
+ if (sun_info.type == RT_STANDARD)
+ {
+ q->blue=ScaleCharToQuantum(*p++);
+ q->green=ScaleCharToQuantum(*p++);
+ q->red=ScaleCharToQuantum(*p++);
+ }
+ else
+ {
+ q->red=ScaleCharToQuantum(*p++);
+ q->green=ScaleCharToQuantum(*p++);
+ q->blue=ScaleCharToQuantum(*p++);
+ }
+ if (image->colors != 0)
+ {
+ q->red=image->colormap[q->red].red;
+ q->green=image->colormap[q->green].green;
+ q->blue=image->colormap[q->blue].blue;
+ }
+ q++;
+ }
+ if ((image->columns % 2) != 0)
+ p++;
+ if (SyncImagePixels(image) == MagickFalse)
+ break;
+ if (image->previous == (Image *) NULL)
+ if ((image->progress_monitor != (MagickProgressMonitor) NULL) &&
(QuantumTick(y,image->rows) != MagickFalse))
- {
+ {
status=image->progress_monitor(LoadImageTag,y,image->rows,
image->client_data);
- if (status == MagickFalse)
+ if (status == MagickFalse)
break;
}
- }
+ }
+ }
if (image->storage_class == PseudoClass)
(void) SyncImage(image);
sun_pixels=(unsigned char *) RelinquishMagickMemory(sun_pixels);
--- coders/xwd.c
+++ coders/xwd.c
@@ -235,6 +235,10 @@
if (header.header_size < sz_XWDheader)
ThrowReaderException(CorruptImageError,"CorruptImage");
length=(size_t) header.header_size-sz_XWDheader;
+ /* new check for CVE-2007-1797 */
+ if (length > ((~0UL)/sizeof(*comment)))
+ ThrowReaderException(CorruptImageError,"ImproperImageHeader");
+
comment=(char *) AcquireMagickMemory(length+MaxTextExtent);
if (comment == (char *) NULL)
ThrowReaderException(ResourceLimitError,"MemoryAllocationFailed");
@@ -266,6 +270,13 @@
ximage->red_mask=header.red_mask;
ximage->green_mask=header.green_mask;
ximage->blue_mask=header.blue_mask;
+ /* Why those are signed ints is beyond me. */
+ if (ximage->depth < 0 || ximage->width < 0 || ximage->height < 0 ||
+ ximage->bitmap_pad < 0 || ximage->bytes_per_line < 0)
+ ThrowReaderException(CorruptImageError,"ImproperImageHeader");
+ /* Guard against buffer overflow in libX11. */
+ if (ximage->bits_per_pixel > 32 || ximage->bitmap_unit > 32)
+ ThrowReaderException(CorruptImageError,"ImproperImageHeader");
x_status=XInitImage(ximage);
if (x_status == 0)
ThrowReaderException(CorruptImageError,"UnableToReadImageHeader");
@@ -278,6 +289,10 @@
XWDColor
color;
+ /* new check for CVE-2007-1797 */
+ if (length > ((~0UL)/sizeof(*colors)))
+ ThrowReaderException(CorruptImageError,"ImproperImageHeader");
+
colors=(XColor *)
AcquireMagickMemory((size_t) header.ncolors*sizeof(*colors));
if (colors == (XColor *) NULL)
@@ -310,11 +325,23 @@
/*
Allocate the pixel buffer.
*/
- if (ximage->format == ZPixmap)
- length=(size_t) ximage->bytes_per_line*ximage->height;
- else
- length=(size_t) ximage->bytes_per_line*ximage->height*ximage->depth;
- ximage->data=(char *) AcquireMagickMemory(length);
+ {
+#define OVERFLOW(c,a,b) ((b) != 0 && ((c)/(b) != (a)))
+ int overflow=0;
+ length=(size_t) ximage->bytes_per_line*ximage->height;
+ if (OVERFLOW(length, (size_t) ximage->bytes_per_line, ximage->height)) overflow=1;
+ if (ximage->format != ZPixmap) {
+ size_t l1=length*ximage->depth;
+ if (OVERFLOW(l1, length, ximage->depth)) overflow=1;
+ length=l1;
+ }
+ if (overflow) {
+ ximage->data = (char *) NULL;
+ } else {
+ ximage->data=(char *) AcquireMagickMemory(length);
+ }
+#undef OVERFLOW
+ }
if (ximage->data == (char *) NULL)
ThrowReaderException(ResourceLimitError,"MemoryAllocationFailed");
count=ReadBlob(image,length,(unsigned char *) ximage->data);