CVE-2018-18544 CVE-2019-7397 CVE-2019-11005 CVE-2019-11006 CVE-2019-11010 CVE-2019-12921 CVE-2020-10938 CVE-2020-12672
297 lines
6.4 KiB
Diff
297 lines
6.4 KiB
Diff
HuffmanDecodeImage(): Fix signed overflow on range check which leads to heap overflow in 32-bit applications. Ascii85Tuple(): Fix thread safety issue.
|
||
(CVE-2020-10938)
|
||
|
||
refers to http://hg.code.sf.net/p/graphicsmagick/code/rev/95abc2b694ce
|
||
|
||
diff -r 751e9e822b09 -r 95abc2b694ce magick/compress.c
|
||
--- a/magick/compress.c Sun Nov 10 13:33:34 2019 -0600
|
||
+++ b/magick/compress.c Sat Nov 16 10:31:37 2019 -0600
|
||
@@ -1,5 +1,5 @@
|
||
/*
|
||
-% Copyright (C) 2003 - 2015 GraphicsMagick Group
|
||
+% Copyright (C) 2003-2019 GraphicsMagick Group
|
||
% Copyright (C) 2002 ImageMagick Studio
|
||
% Copyright 1991-1999 E. I. du Pont de Nemours and Company
|
||
%
|
||
@@ -53,21 +53,26 @@
|
||
*/
|
||
typedef struct HuffmanTable
|
||
{
|
||
+ unsigned int
|
||
+ id;
|
||
+
|
||
int
|
||
- id,
|
||
- code,
|
||
+ code;
|
||
+
|
||
+ unsigned int
|
||
length,
|
||
count;
|
||
+
|
||
} HuffmanTable;
|
||
|
||
/*
|
||
Huffman coding declarations.
|
||
*/
|
||
-#define TWId 23
|
||
-#define MWId 24
|
||
-#define TBId 25
|
||
-#define MBId 26
|
||
-#define EXId 27
|
||
+#define TWId 23U
|
||
+#define MWId 24U
|
||
+#define TBId 25U
|
||
+#define MBId 26U
|
||
+#define EXId 27U
|
||
|
||
static const HuffmanTable
|
||
MBTable[]=
|
||
@@ -202,37 +207,38 @@
|
||
*/
|
||
#define MaxLineExtent 36
|
||
|
||
-static char *Ascii85Tuple(unsigned char *data)
|
||
+static char *Ascii85Tuple(char tuple[6], const unsigned char * restrict data)
|
||
{
|
||
- static char
|
||
- tuple[6];
|
||
+ magick_uint32_t
|
||
+ code;
|
||
|
||
- register long
|
||
- i,
|
||
- x;
|
||
-
|
||
- unsigned long
|
||
- code,
|
||
- quantum;
|
||
-
|
||
- code=((((unsigned long) data[0] << 8) | (unsigned long) data[1]) << 16) |
|
||
- ((unsigned long) data[2] << 8) | (unsigned long) data[3];
|
||
- if (code == 0L)
|
||
+ code=((((magick_uint32_t) data[0] << 8) | (magick_uint32_t) data[1]) << 16) |
|
||
+ ((magick_uint32_t) data[2] << 8) | (magick_uint32_t) data[3];
|
||
+ if (code == 0)
|
||
{
|
||
tuple[0]='z';
|
||
tuple[1]='\0';
|
||
- return(tuple);
|
||
}
|
||
- quantum=85UL*85UL*85UL*85UL;
|
||
- for (i=0; i < 4; i++)
|
||
- {
|
||
- x=(long) (code/quantum);
|
||
- code-=quantum*x;
|
||
- tuple[i]=(char) (x+(int) '!');
|
||
- quantum/=85L;
|
||
- }
|
||
- tuple[4]=(char) ((code % 85L)+(int) '!');
|
||
- tuple[5]='\0';
|
||
+ else
|
||
+ {
|
||
+ register magick_int32_t
|
||
+ i,
|
||
+ x;
|
||
+
|
||
+ magick_uint32_t
|
||
+ quantum;
|
||
+
|
||
+ quantum=85U*85U*85U*85U;
|
||
+ for (i=0; i < 4; i++)
|
||
+ {
|
||
+ x=(magick_int32_t) (code/quantum);
|
||
+ code-=quantum*x;
|
||
+ tuple[i]=(char) (x+(int) '!');
|
||
+ quantum/=85;
|
||
+ }
|
||
+ tuple[4]=(char) ((code % 85)+(int) '!');
|
||
+ tuple[5]='\0';
|
||
+ }
|
||
return(tuple);
|
||
}
|
||
|
||
@@ -255,6 +261,9 @@
|
||
|
||
MagickExport void Ascii85Flush(Image *image)
|
||
{
|
||
+ char
|
||
+ tuple_buff[6];
|
||
+
|
||
register char
|
||
*tuple;
|
||
|
||
@@ -266,7 +275,7 @@
|
||
image->ascii85->buffer[image->ascii85->offset]=0;
|
||
image->ascii85->buffer[image->ascii85->offset+1]=0;
|
||
image->ascii85->buffer[image->ascii85->offset+2]=0;
|
||
- tuple=Ascii85Tuple(image->ascii85->buffer);
|
||
+ tuple=Ascii85Tuple(tuple_buff, image->ascii85->buffer);
|
||
(void) WriteBlob(image,image->ascii85->offset+1,
|
||
*tuple == 'z' ? "!!!!" : tuple);
|
||
}
|
||
@@ -286,6 +295,9 @@
|
||
register unsigned char
|
||
*p;
|
||
|
||
+ char
|
||
+ tuple_buff[6];
|
||
+
|
||
assert(image != (Image *) NULL);
|
||
assert(image->signature == MagickSignature);
|
||
assert(image->ascii85 != (Ascii85Info *) NULL);
|
||
@@ -296,7 +308,7 @@
|
||
p=image->ascii85->buffer;
|
||
for (n=image->ascii85->offset; n >= 4; n-=4)
|
||
{
|
||
- for (q=Ascii85Tuple(p); *q; q++)
|
||
+ for (q=Ascii85Tuple(tuple_buff,p); *q; q++)
|
||
{
|
||
image->ascii85->line_break--;
|
||
if ((image->ascii85->line_break < 0) && (*q != '%'))
|
||
@@ -355,11 +367,11 @@
|
||
%
|
||
%
|
||
*/
|
||
-#define HashSize 1021
|
||
-#define MBHashA 293
|
||
-#define MBHashB 2695
|
||
-#define MWHashA 3510
|
||
-#define MWHashB 1178
|
||
+#define HashSize 1021U
|
||
+#define MBHashA 293U
|
||
+#define MBHashB 2695U
|
||
+#define MWHashA 3510U
|
||
+#define MWHashB 1178U
|
||
|
||
#define InitializeHashTable(hash,table,a,b) \
|
||
{ \
|
||
@@ -401,26 +413,30 @@
|
||
byte,
|
||
code,
|
||
color,
|
||
- length,
|
||
null_lines,
|
||
runlength;
|
||
|
||
unsigned int
|
||
bit,
|
||
index,
|
||
+ length,
|
||
mask;
|
||
|
||
long
|
||
- count,
|
||
+ count;
|
||
+
|
||
+ unsigned long
|
||
y;
|
||
|
||
register IndexPacket
|
||
*indexes;
|
||
|
||
- register long
|
||
- i,
|
||
+ register unsigned long
|
||
x;
|
||
|
||
+ unsigned int
|
||
+ i;
|
||
+
|
||
register PixelPacket
|
||
*q;
|
||
|
||
@@ -481,13 +497,13 @@
|
||
image->x_resolution=204.0;
|
||
image->y_resolution=196.0;
|
||
image->units=PixelsPerInchResolution;
|
||
- for (y=0; ((y < (long) image->rows) && (null_lines < 3)); )
|
||
+ for (y=0; ((y < image->rows) && (null_lines < 3)); )
|
||
{
|
||
/*
|
||
Initialize scanline to white.
|
||
*/
|
||
p=scanline;
|
||
- for (x=0; x < (long) image->columns; x++)
|
||
+ for (x=0; x < image->columns; x++)
|
||
*p++=0;
|
||
/*
|
||
Decode Huffman encoded scanline.
|
||
@@ -502,7 +518,7 @@
|
||
{
|
||
if (byte == EOF)
|
||
break;
|
||
- if (x >= (long) image->columns)
|
||
+ if (x >= image->columns)
|
||
{
|
||
while (runlength < 11)
|
||
InputBit(bit);
|
||
@@ -563,7 +579,7 @@
|
||
case TBId:
|
||
{
|
||
count+=entry->count;
|
||
- if ((x+count) > (long) image->columns)
|
||
+ if ((x+(unsigned long) count) > image->columns)
|
||
count=(long) image->columns-x;
|
||
if (count > 0)
|
||
{
|
||
@@ -603,7 +619,7 @@
|
||
break;
|
||
}
|
||
indexes=AccessMutableIndexes(image);
|
||
- for (x=0; x < (long) image->columns; x++)
|
||
+ for (x=0; x < image->columns; x++)
|
||
{
|
||
index=(unsigned int) (*p++);
|
||
indexes[x]=index;
|
||
@@ -695,7 +711,9 @@
|
||
runlength;
|
||
|
||
long
|
||
- n,
|
||
+ n;
|
||
+
|
||
+ unsigned long
|
||
y;
|
||
|
||
Image
|
||
@@ -704,8 +722,10 @@
|
||
register const IndexPacket
|
||
*indexes;
|
||
|
||
- register long
|
||
- i,
|
||
+ unsigned long
|
||
+ i;
|
||
+
|
||
+ register unsigned long
|
||
x;
|
||
|
||
register const PixelPacket
|
||
@@ -772,10 +792,10 @@
|
||
polarity=(PixelIntensityToQuantum(&huffman_image->colormap[0]) <
|
||
PixelIntensityToQuantum(&huffman_image->colormap[1]) ? 0x00 : 0x01);
|
||
q=scanline;
|
||
- for (i=(long) width; i > 0; i--)
|
||
+ for (i=0; i < width; i++) /* was: for (i=(long) width; i > 0; i--) */
|
||
*q++=(unsigned char) polarity;
|
||
q=scanline;
|
||
- for (y=0; y < (long) huffman_image->rows; y++)
|
||
+ for (y=0; y < huffman_image->rows; y++)
|
||
{
|
||
p=AcquireImagePixels(huffman_image,0,y,huffman_image->columns,1,
|
||
&huffman_image->exception);
|
||
@@ -785,7 +805,7 @@
|
||
break;
|
||
}
|
||
indexes=AccessImmutableIndexes(huffman_image);
|
||
- for (x=0; x < (long) huffman_image->columns; x++)
|
||
+ for (x=0; x < huffman_image->columns; x++)
|
||
{
|
||
*q=(unsigned char) (indexes[x] == polarity ? !polarity : polarity);
|
||
q++;
|
||
|
||
|
||
|
||
|