From 58acc80aaacb0fe7dc9fd503904f49e21a51e94b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bastien=20ROUCARI=C3=88S?= <roucaries.bastien@gmail.com> Date: Tue, 10 Apr 2012 17:13:40 +0200 Subject: [PATCH] Fix security bug for special crafted EXIF properties The original patch for CVE-2012-0259 turned out to be insufficient. The problem is an integer overflow error in the "GetEXIFProperty()" function (magick/property.c, around line 1288): number_bytes=(size_t) components*tag_bytes[format]; When processing EXIF directory entries with tags of e.g. format 5 (EXIF_FMT_URATIONAL) and a large components count, the calculation can overflow and e.g. lead to "number_bytes" being 0. If that's the case, subsequent checks can be bypassed, resulting in the loop in the "EXIFMultipleFractions" macro to iterate through a large number of "components". This leads to out-of-bound reads until eventually causing a segmentation fault when trying to read beyond the limits of heap memory. CVE-2012-1610 has been assigned to this issue. Note: The initial patch for this issue is still necessary to prevent access of uninitialized/incorrect memory when e.g. processing specially crafted EXIF tags with a component count of 0. Origin: upstream Applied-Upstream: 6.7.6-4 Bug-Debian: http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=667635 --- magick/profile.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/magick/profile.c b/magick/profile.c index 1405029..07e5c32 100644 --- a/magick/profile.c +++ b/magick/profile.c @@ -6707,7 +6707,7 @@ MagickExport MagickBooleanType SyncImageProfiles(Image *image) number_entries=ReadProfileShort(endian,directory); for ( ; entry < number_entries; entry++) { - int + ssize_t components; register unsigned char @@ -6729,8 +6729,10 @@ MagickExport MagickBooleanType SyncImageProfiles(Image *image) format=(ssize_t) ReadProfileShort(endian,q+2); if ((format-1) >= EXIF_NUM_FORMATS) break; - components=(int) ReadProfileLong(endian,q+4); + components=(ssize_t) ((int) ReadProfileLong(endian,q+4)); number_bytes=(size_t) components*format_bytes[format]; + if (number_bytes < components) + break; if (number_bytes <= 4) p=q+8; else -- 1.7.10