From 3c23dfbe1c4c3446fc0c6ab5095e6f9c488ec34f Mon Sep 17 00:00:00 2001 From: caodongxia <315816521@qq.com> Date: Mon, 7 Dec 2020 18:22:24 +0800 Subject: [PATCH] create patch diff --git a/ChangeLog b/ChangeLog index 4284834..a89c828 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,12 @@ +2019-04-17 Bob Friesenhahn + * coders/xwd.c (ReadXWDImage): Added even more XWD header + validation logic. Addresses problems noted by email from Hongxu + Chen to the graphicsmagick-security mail alias on Wed, 17 Apr 2019 + and entitled "Multiple crashes (FPE and invalid read) when + processing XWD files". Also addresses additional issues noted + that an attacker could request to allocate an arbitrary amount of + memory based on ncolors and the claimed header size. + 2018-06-23 Bob Friesenhahn * version.sh: Update library versioning for 1.3.30 release. diff --git a/coders/xwd.c b/coders/xwd.c index 9f9b850..caff995 100644 --- a/coders/xwd.c +++ b/coders/xwd.c @@ -225,7 +225,6 @@ static MagickPassFail BytesPerLine(size_t *bytes_per_line, */ #define ThrowXWDReaderException(code_,reason_,image_) \ do { \ - MagickFreeMemory(comment); \ if (ximage) \ MagickFreeMemory(ximage->data); \ MagickFreeMemory(ximage); \ @@ -236,8 +235,7 @@ do { \ static Image *ReadXWDImage(const ImageInfo *image_info,ExceptionInfo *exception) { char - *comment = (char *) NULL; - + comment[MaxTextExtent]; Image *image; @@ -320,7 +318,7 @@ static Image *ReadXWDImage(const ImageInfo *image_info,ExceptionInfo *exception) ThrowXWDReaderException(CorruptImageError,InvalidFileFormatVersion,image); if (header.header_size < sz_XWDheader) ThrowXWDReaderException(CorruptImageError,ImproperImageHeader,image); - + /* Display classes used in opening the connection */ switch (header.visual_class) { case StaticGray: @@ -335,11 +333,18 @@ static Image *ReadXWDImage(const ImageInfo *image_info,ExceptionInfo *exception) ThrowXWDReaderException(CorruptImageError,ImproperImageHeader,image); } } + + /* XYBitmap, XYPixmap, ZPixmap */ switch (header.pixmap_format) { - case XYBitmap: - case XYPixmap: - case ZPixmap: + case XYBitmap: /* 1 bit bitmap format */ + if (header.pixmap_depth != 1) + ThrowXWDReaderException(CorruptImageError,ImproperImageHeader,image); + break; + case XYPixmap: /* Single plane bitmap. */ + case ZPixmap: /* Bitmap with 2 or more planes */ + if ((header.pixmap_depth < 1) || (header.pixmap_depth > 32)) + ThrowXWDReaderException(CorruptImageError,ImproperImageHeader,image); break; default: { @@ -347,8 +352,80 @@ static Image *ReadXWDImage(const ImageInfo *image_info,ExceptionInfo *exception) } } - if ((header.bits_per_pixel == 0) || (header.bits_per_pixel > 32)) + /* Data byte order, LSBFirst, MSBFirst */ + switch (header.byte_order) + { + case LSBFirst: + case MSBFirst: + break; + default: + { + ThrowXWDReaderException(CorruptImageError,ImproperImageHeader,image); + } + } + /* Quant. of scanline 8, 16, 32 */ + switch (header.bitmap_unit) + { + case 8: + case 16: + case 32: + break; + default: + { + ThrowXWDReaderException(CorruptImageError,ImproperImageHeader,image); + } + } + /* LSBFirst, MSBFirst */ + switch (header.bitmap_bit_order) + { + case LSBFirst: + case MSBFirst: + break; + default: + { + ThrowXWDReaderException(CorruptImageError,ImproperImageHeader,image); + } + } + /* 8, 16, 32 either XY or ZPixmap */ + if ((header.pixmap_format == XYPixmap) || (header.pixmap_format == ZPixmap)) + switch (header.bitmap_pad) + { + case 8: + case 16: + case 32: + break; + default: + { + ThrowXWDReaderException(CorruptImageError,ImproperImageHeader,image); + } + } + /* Bits per pixel (ZPixmap) */ + switch (header.visual_class) + { + case StaticGray: + case GrayScale: + /* Gray-scale image */ + if (header.bits_per_pixel != 1) + ThrowXWDReaderException(CorruptImageError,ImproperImageHeader,image); + break; + case StaticColor: + case PseudoColor: + /* Color-mapped image */ + if ((header.bits_per_pixel < 1) || (header.bits_per_pixel > 15) || (header.ncolors == 0)) + ThrowXWDReaderException(CorruptImageError,ImproperImageHeader,image); + break; + case TrueColor: + case DirectColor: + /* True-color image */ + if ((header.bits_per_pixel != 16) && (header.bits_per_pixel != 24) && (header.bits_per_pixel != 32)) + ThrowXWDReaderException(CorruptImageError,ImproperImageHeader,image); + break; + } + /* Place an arbitrary limit on colormap size */ + if (header.ncolors > 4096) ThrowXWDReaderException(CorruptImageError,ImproperImageHeader,image); + + /* 8, 16, 32 either XY or ZPixmap */ if ((header.bitmap_pad % 8 != 0) || (header.bitmap_pad > 32)) ThrowXWDReaderException(CorruptImageError,ImproperImageHeader,image); @@ -377,18 +454,14 @@ static Image *ReadXWDImage(const ImageInfo *image_info,ExceptionInfo *exception) Retrieve comment (if any) */ length=header.header_size-sz_XWDheader; - if (length > ((~0UL)/sizeof(*comment))) + if (length >= MaxTextExtent) ThrowXWDReaderException(CorruptImageError,ImproperImageHeader,image); - comment=MagickAllocateMemory(char *,length+1); - if (comment == (char *) NULL) - ThrowXWDReaderException(ResourceLimitError,MemoryAllocationFailed,image); count=ReadBlob(image,length,comment); if (count != length) ThrowXWDReaderException(CorruptImageError,UnableToReadWindowNameFromDumpFile, image); comment[length]='\0'; (void) SetImageAttribute(image,"comment",comment); - MagickFreeMemory(comment); /* Initialize the X image. @@ -417,6 +490,7 @@ static Image *ReadXWDImage(const ImageInfo *image_info,ExceptionInfo *exception) */ if (ximage->width < 0 || ximage->height < 0 || + ximage->xoffset < 0 || ximage->format < 0 || ximage->byte_order < 0 || ximage->bitmap_unit < 0 || @@ -439,10 +513,14 @@ static Image *ReadXWDImage(const ImageInfo *image_info,ExceptionInfo *exception) if (CheckImagePixelLimits(image, exception) != MagickPass) ThrowXWDReaderException(ResourceLimitError,ImagePixelLimitExceeded,image); image->depth=8; - if ((header.ncolors == 0U) || - ((ximage->red_mask != 0) || - (ximage->green_mask != 0) || - (ximage->blue_mask != 0))) + /* + FIXME: This block of logic should be re-worked. + */ + if ((header.visual_class != StaticGray) && + ((header.ncolors == 0U) || + ((ximage->red_mask != 0) || + (ximage->green_mask != 0) || + (ximage->blue_mask != 0)))) { image->storage_class=DirectClass; if (!image_info->ping) @@ -454,7 +532,7 @@ static Image *ReadXWDImage(const ImageInfo *image_info,ExceptionInfo *exception) else { image->storage_class=PseudoClass; - image->colors=header.ncolors; + image->colors=header.visual_class == StaticGray ? 2 : header.ncolors; /* FIXME! */ } if (!image_info->ping) { @@ -467,17 +545,13 @@ static Image *ReadXWDImage(const ImageInfo *image_info,ExceptionInfo *exception) XWDColor color; - register long + register unsigned int i; - - length=(size_t) header.ncolors; - if (length > ((~0UL)/sizeof(*colors))) - ThrowXWDReaderException(CorruptImageError,ImproperImageHeader,image); - colors=MagickAllocateArray(XColor *,length,sizeof(XColor)); + colors=MagickAllocateArray(XColor *,header.ncolors,sizeof(XColor)); if (colors == (XColor *) NULL) ThrowXWDReaderException(ResourceLimitError,MemoryAllocationFailed, image); - for (i=0; i < (long) header.ncolors; i++) + for (i=0; i < header.ncolors; i++) { count=ReadBlob(image,sz_XWDColor,(char *) &color); if (count != sz_XWDColor) @@ -494,7 +568,7 @@ static Image *ReadXWDImage(const ImageInfo *image_info,ExceptionInfo *exception) */ lsb_first=1; if (*(char *) &lsb_first) - for (i=0; i < (long) header.ncolors; i++) + for (i=0; i < header.ncolors; i++) { MSBOrderLong((unsigned char *) &colors[i].pixel, sizeof(unsigned long)); @@ -508,15 +582,14 @@ static Image *ReadXWDImage(const ImageInfo *image_info,ExceptionInfo *exception) /* Allocate the pixel buffer. */ -#define XWD_OVERFLOW(c,a,b) ((b) != 0 && ((c)/((size_t) b) != ((size_t) a))) + length=MagickArraySize(ximage->bytes_per_line,ximage->height); length=ximage->bytes_per_line*ximage->height; - if (XWD_OVERFLOW(length,ximage->bytes_per_line,ximage->height)) + if (0 == length) ThrowXWDReaderException(ResourceLimitError,MemoryAllocationFailed,image); if (ximage->format != ZPixmap) { - size_t tmp=length; - length*=ximage->depth; - if (XWD_OVERFLOW(length,tmp,ximage->depth)) + length=MagickArraySize(length,ximage->depth); + if (0 == length) ThrowXWDReaderException(ResourceLimitError,MemoryAllocationFailed, image); } @@ -658,17 +731,21 @@ static Image *ReadXWDImage(const ImageInfo *image_info,ExceptionInfo *exception) /* Convert X image to PseudoClass packets. */ - register long + register unsigned int i; if (!AllocateImageColormap(image,image->colors)) ThrowXWDReaderException(ResourceLimitError,MemoryAllocationFailed, image); - for (i=0; i < (long) image->colors; i++) - { - image->colormap[i].red=ScaleShortToQuantum(colors[i].red); - image->colormap[i].green=ScaleShortToQuantum(colors[i].green); - image->colormap[i].blue=ScaleShortToQuantum(colors[i].blue); + if (colors != (XColor *) NULL) + { + const unsigned int min_colors = Min(image->colors,header.ncolors); + for (i=0; i < min_colors; i++) + { + image->colormap[i].red=ScaleShortToQuantum(colors[i].red); + image->colormap[i].green=ScaleShortToQuantum(colors[i].green); + image->colormap[i].blue=ScaleShortToQuantum(colors[i].blue); + } } for (y=0; y < (long) image->rows; y++) { diff --git a/magick/version.h b/magick/version.h index 527a09a..a9e0dca 100644 --- a/magick/version.h +++ b/magick/version.h @@ -38,8 +38,8 @@ extern "C" { #define MagickLibVersion 0x211801 #define MagickLibVersionText "1.3.30" #define MagickLibVersionNumber 21,18,1 -#define MagickChangeDate "20180623" -#define MagickReleaseDate "2018-06-23" +#define MagickChangeDate "20190417" +#define MagickReleaseDate "snapshot-20190417" /* The MagickLibInterfaceNewest and MagickLibInterfaceOldest defines diff --git a/www/Changelog.html b/www/Changelog.html index f1ab73c..e5a21da 100644 --- a/www/Changelog.html +++ b/www/Changelog.html @@ -34,6 +34,18 @@
+

2019-04-17 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>

+
+
    +
  • coders/xwd.c (ReadXWDImage): Added even more XWD header +validation logic. Addresses problems noted by email from Hongxu +Chen to the graphicsmagick-security mail alias on Wed, 17 Apr 2019 +and entitled "Multiple crashes (FPE and invalid read) when +processing XWD files". Also addresses additional issues noted +that an attacker could request to allocate an arbitrary amount of +memory based on ncolors and the claimed header size.
  • +
+

2018-06-23 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>

-- 2.27.0