File ImageMagick-security-dos.patch of Package ImageMagick
--- ImageMagick-6.5.4-8/magick/profile.c.orig 2012-06-05 11:25:53.406802312 +0200
+++ ImageMagick-6.5.4-8/magick/profile.c 2012-06-06 17:54:50.010100732 +0200
@@ -1631,14 +1631,15 @@
EndianType
endian;
- long
- id,
- level;
+ SplayTreeInfo
+ *exif_resources;
size_t
length;
ssize_t
+ id,
+ level,
offset;
static int
@@ -1695,12 +1696,14 @@
/*
This the offset to the first IFD.
*/
- offset=(ssize_t) ReadProfileLong(endian,exif+4);
- if ((size_t) offset >= length)
+ offset=(ssize_t) ((int) ReadProfileLong(endian,exif+4));
+ if ((offset < 0) || ((size_t) offset >= length))
return(MagickFalse);
directory=exif+offset;
level=0;
entry=0;
+ exif_resources=NewSplayTree((int (*)(const void *,const void *)) NULL,
+ (void *(*)(void *)) NULL,(void *(*)(void *)) NULL);
do
{
if (level > 0)
@@ -1728,6 +1731,9 @@
number_bytes;
q=(unsigned char *) (directory+2+(12*entry));
+ if (GetValueFromSplayTree(exif_resources,q) == q)
+ break;
+ (void) AddValueToSplayTree(exif_resources,q,q);
tag_value=(long) ReadProfileShort(endian,q);
format=(long) ReadProfileShort(endian,q+2);
if ((format-1) >= EXIF_NUM_FORMATS)
@@ -1744,7 +1750,9 @@
/*
The directory entry contains an offset.
*/
- offset=(ssize_t) ReadProfileLong(endian,q+8);
+ offset=(ssize_t) ((int) ReadProfileLong(endian,q+8));
+ if ((offset+number_bytes) < offset)
+ continue; /* prevent overflow */
if ((size_t) (offset+number_bytes) > length)
continue;
p=(unsigned char *) (exif+offset);
@@ -1783,11 +1791,11 @@
}
if ((tag_value == TAG_EXIF_OFFSET) || (tag_value == TAG_INTEROP_OFFSET))
{
- size_t
+ ssize_t
offset;
- offset=(size_t) ReadProfileLong(endian,p);
- if ((offset < length) && (level < (MaxDirectoryStack-2)))
+ offset=(ssize_t) ((int) ReadProfileLong(endian,p));
+ if (((size_t) offset < length) && (level < (MaxDirectoryStack-2)))
{
directory_stack[level].directory=directory;
entry++;
@@ -1798,9 +1806,9 @@
level++;
if ((directory+2+(12*number_entries)) > (exif+length))
break;
- offset=(size_t) ReadProfileLong(endian,directory+2+(12*
- number_entries));
- if ((offset != 0) && (offset < length) &&
+ offset=(ssize_t) ((int) ReadProfileLong(endian,directory+2+(12*
+ number_entries)));
+ if ((offset != 0) && ((size_t) offset < length) &&
(level < (MaxDirectoryStack-2)))
{
directory_stack[level].directory=exif+offset;
@@ -1812,5 +1820,6 @@
}
}
} while (level > 0);
+ exif_resources=DestroySplayTree(exif_resources);
return(MagickTrue);
}
--- ImageMagick-6.5.4-8/magick/property.c.orig 2012-06-05 11:25:53.406802312 +0200
+++ ImageMagick-6.5.4-8/magick/property.c 2012-06-06 18:07:50.194124299 +0200
@@ -453,6 +453,13 @@
return(y);
}
+static inline ssize_t MagickMin(const ssize_t x,const ssize_t y)
+{
+ if (x < y)
+ return(x);
+ return(y);
+}
+
static inline int ReadPropertyByte(const unsigned char **p,size_t *length)
{
int
@@ -587,7 +594,7 @@
continue;
if (ReadPropertyByte(&info,&length) != (unsigned char) 'M')
continue;
- id=(long) ReadPropertyMSBShort(&info,&length);
+ id=(ssize_t) ((int) ReadPropertyMSBShort(&info,&length));
if (id < start)
continue;
if (id > stop)
@@ -618,7 +625,7 @@
No name match, scroll forward and try next.
*/
info+=count;
- length-=count;
+ length-=MagickMin(count,(ssize_t) length);
continue;
}
if ((*name == '#') && (sub_number != 1))
@@ -628,7 +635,7 @@
*/
sub_number--;
info+=count;
- length-=count;
+ length-=MagickMin(count,(ssize_t) length);
continue;
}
/*
@@ -643,7 +650,7 @@
(void) CopyMagickMemory(attribute,(char *) info,(size_t) count);
attribute[count]='\0';
info+=count;
- length-=count;
+ length-=MagickMin(count,(ssize_t) length);
if ((id <= 1999) || (id >= 2999))
(void) SetImageProperty((Image *) image,key,(const char *)
attribute);
@@ -783,7 +790,9 @@
*directory;
unsigned long
- entry,
+ entry;
+
+ ssize_t
offset;
} DirectoryInfo;
@@ -1087,6 +1096,7 @@
all,
id,
level,
+ tag_offset,
tag_value;
register long
@@ -1104,9 +1114,11 @@
unsigned long
entry,
number_entries,
- tag_offset,
tag;
+ SplayTreeInfo
+ *exif_resources;
+
/*
If EXIF data exists, then try to parse the request for a tag.
*/
@@ -1217,7 +1229,7 @@
}
if (length < 16)
return(MagickFalse);
- id=(long) ReadPropertyShort(LSBEndian,exif);
+ id=(ssize_t) ((int) ReadPropertyShort(LSBEndian,exif));
endian=LSBEndian;
if (id == 0x4949)
endian=LSBEndian;
@@ -1232,7 +1244,7 @@
This the offset to the first IFD.
*/
offset=(ssize_t) ReadPropertyLong(endian,exif+4);
- if ((size_t) offset >= length)
+ if ((offset < 0) || (size_t) offset >= length)
return(MagickFalse);
/*
Set the pointer to the first IFD and follow it were it leads.
@@ -1241,6 +1253,8 @@
level=0;
entry=0;
tag_offset=0;
+ exif_resources=NewSplayTree((int (*)(const void *,const void *)) NULL,
+ (void *(*)(void *)) NULL,(void *(*)(void *)) NULL);
do
{
/*
@@ -1256,7 +1270,7 @@
/*
Determine how many entries there are in the current IFD.
*/
- number_entries=ReadPropertyShort(endian,directory);
+ number_entries=(size_t) ((int) ReadPropertyShort(endian,directory));
for ( ; entry < number_entries; entry++)
{
long
@@ -1272,9 +1286,12 @@
unsigned long
format;
- q=(unsigned char *) (directory+2+(12*entry));
- tag_value=(long) ReadPropertyShort(endian,q)+tag_offset;
- format=(unsigned long) ReadPropertyShort(endian,q+2);
+ q=(unsigned char *) (directory+(12*entry)+2);
+ if (GetValueFromSplayTree(exif_resources,q) == q)
+ break;
+ (void) AddValueToSplayTree(exif_resources,q,q);
+ tag_value=(ssize_t) ((int) ReadPropertyShort(endian,q)+tag_offset);
+ format=(size_t) ((int) ReadPropertyShort(endian,q+2));
if (format >= (sizeof(tag_bytes)/sizeof(*tag_bytes)))
break;
components=(long) ReadPropertyLong(endian,q+4);
@@ -1290,6 +1307,8 @@
The directory entry contains an offset.
*/
offset=(ssize_t) ReadPropertyLong(endian,q+8);
+ if ((offset+number_bytes) < offset)
+ continue; /* prevent overflow */
if ((size_t) (offset+number_bytes) > length)
continue;
p=(unsigned char *) (exif+offset);
@@ -1337,7 +1356,7 @@
case EXIF_FMT_URATIONAL:
{
EXIFMultipleFractions(8,"%ld/%ld",ReadPropertyLong(endian,p1),
- ReadPropertyLong(endian,p1+4));
+ ((int) ReadPropertyLong(endian,p1+4)));
break;
}
case EXIF_FMT_SRATIONAL:
@@ -1440,16 +1459,17 @@
(tag_value == TAG_INTEROP_OFFSET) ||
(tag_value == TAG_GPS_OFFSET))
{
- size_t
+ ssize_t
offset;
- offset=(size_t) ReadPropertyLong(endian,p);
- if ((offset < length) && (level < (MaxDirectoryStack-2)))
+ offset=(ssize_t) ((int) ReadPropertyLong(endian,p));
+ if (((size_t) offset < length) && (level < (MaxDirectoryStack-2)))
{
- unsigned long
+ ssize_t
tag_offset1;
- tag_offset1=(tag_value == TAG_GPS_OFFSET) ? 0x10000UL : 0UL;
+ tag_offset1=(ssize_t) ((tag_value == TAG_GPS_OFFSET) ? 0x10000 :
+ 0);
directory_stack[level].directory=directory;
entry++;
directory_stack[level].entry=entry;
@@ -1461,9 +1481,9 @@
level++;
if ((directory+2+(12*number_entries)) > (exif+length))
break;
- offset=(size_t) ReadPropertyLong(endian,directory+2+(12*
- number_entries));
- if ((offset != 0) && (offset < length) &&
+ offset=(ssize_t) ((int) ReadPropertyLong(endian,directory+2+(12*
+ number_entries)));
+ if ((offset != 0) && ((size_t) offset < length) &&
(level < (MaxDirectoryStack-2)))
{
directory_stack[level].directory=exif+offset;
@@ -1476,6 +1496,7 @@
}
}
} while (level > 0);
+ exif_resources=DestroySplayTree(exif_resources);
return(MagickTrue);
}
@@ -1617,7 +1638,7 @@
in_subpath=MagickFalse;
while (length > 0)
{
- selector=(long) ReadPropertyMSBShort(&blob,&length);
+ selector=(ssize_t) ((int) ReadPropertyMSBShort(&blob,&length));
switch (selector)
{
case 0:
@@ -1626,15 +1647,15 @@
if (knot_count != 0)
{
blob+=24;
- length-=24;
+ length-=MagickMin(24,(ssize_t) length);
break;
}
/*
Expected subpath length record.
*/
- knot_count=(long) ReadPropertyMSBShort(&blob,&length);
+ knot_count=(ssize_t) ((int) ReadPropertyMSBShort(&blob,&length));
blob+=22;
- length-=22;
+ length-=MagickMin(22,(ssize_t) length);
break;
}
case 1:
@@ -1648,7 +1669,7 @@
Unexpected subpath knot
*/
blob+=24;
- length-=24;
+ length-=MagickMin(24,(ssize_t) length);
break;
}
/*
@@ -1656,8 +1677,8 @@
*/
for (i=0; i < 3; i++)
{
- y=(long) ReadPropertyMSBLong(&blob,&length);
- x=(long) ReadPropertyMSBLong(&blob,&length);
+ y=(size_t) ((int) ReadPropertyMSBLong(&blob,&length));
+ x=(size_t) ((int) ReadPropertyMSBLong(&blob,&length));
point[i].x=(double) x/4096/4096;
point[i].y=1.0-(double) y/4096/4096;
}
@@ -1739,7 +1760,7 @@
default:
{
blob+=24;
- length-=24;
+ length-=MagickMin(24,(ssize_t) length);
break;
}
}
@@ -1804,7 +1825,7 @@
in_subpath=MagickFalse;
while (length != 0)
{
- selector=(long) ReadPropertyMSBShort(&blob,&length);
+ selector=(ssize_t) ((int) ReadPropertyMSBShort(&blob,&length));
switch (selector)
{
case 0:
@@ -1813,15 +1834,15 @@
if (knot_count != 0)
{
blob+=24;
- length-=24;
+ length-=MagickMin(24,(ssize_t) length);
break;
}
/*
Expected subpath length record.
*/
- knot_count=(long) ReadPropertyMSBShort(&blob,&length);
+ knot_count=(ssize_t) ((int) ReadPropertyMSBShort(&blob,&length));
blob+=22;
- length-=22;
+ length-=MagickMin(22,(ssize_t) length);
break;
}
case 1:
@@ -1902,7 +1923,7 @@
default:
{
blob+=24;
- length-=24;
+ length-=MagickMin(24,(ssize_t) length);
break;
}
}