diff --git a/CVE-2019-11473-CVE-2019-11474.patch b/CVE-2019-11473-CVE-2019-11474.patch new file mode 100644 index 0000000000000000000000000000000000000000..15d294f47ab803a156317df0b0f3e52cbba6c359 --- /dev/null +++ b/CVE-2019-11473-CVE-2019-11474.patch @@ -0,0 +1,333 @@ +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 + diff --git a/GraphicsMagick.spec b/GraphicsMagick.spec index 2e64407df58e1d61efccf9b9a92b2546c55a5ac4..2fb5a3ca370b9adddca8112f88758b224ea71ee4 100644 --- a/GraphicsMagick.spec +++ b/GraphicsMagick.spec @@ -10,7 +10,7 @@ Name: GraphicsMagick Version: 1.3.30 -Release: 7 +Release: 8 Summary: Derived from ImageMagick, providing faster image generation speed and better quality License: MIT Source0: http://downloads.sourceforge.net/sourceforge/graphicsmagick/GraphicsMagick-%{version}.tar.xz @@ -31,6 +31,7 @@ Patch0011: CVE-2019-11010.patch Patch0012: CVE-2019-12921.patch Patch0013: CVE-2020-10938.patch Patch0014: CVE-2020-12672.patch +Patch0015: CVE-2019-11473-CVE-2019-11474.patch BuildRequires: bzip2-devel freetype-devel gcc-c++ giflib-devel lcms2-devel libjpeg-devel BuildRequires: libpng-devel librsvg2-devel libtiff-devel libtool-ltdl-devel libxml2-devel lpr @@ -229,6 +230,9 @@ time %make_build check ||: %changelog +* Mon Dec 07 2020 caodongxia - 1.3.30-8 +- fix CVE-2019-11473 CVE-2019-11474 + * Sat Sep 19 2020 maminjie - 1.3.30-7 - fix some CVEs: CVE-2018-18544 CVE-2019-7397 CVE-2019-11005 CVE-2019-11006 CVE-2019-11010 CVE-2019-12921 CVE-2020-10938 CVE-2020-12672