Integer and Buffer overflow in coders/icon.c

Bug #1459747 reported by Moshe Kaplan on 2015-05-28
258
This bug affects 1 person
Affects Status Importance Assigned to Milestone
imagemagick (Ubuntu)
Undecided
Unassigned

Bug Description

Bug summary: Memory is allocated based on the sum of a user-supplied value and a fixed value. That sum can overflow, causing only a small amount of memory to be allocated, while the program assumes more was allocated.

The bug is present in both Ubuntu's release 6.8.9.9 and the most recent release of Imagemagick, Version 6.9.1-3

This bug was found by examining code that matched the following regex: AcquireQuantumMemory\(([a-zA-Z0-9>-]+)[*+]([a-zA-Z0-9]+)

Technical details:
On line 313, icon_file.directory[i].size=ReadBlobLSBLong(image); reads in a 4byte value from the image and stores it in icon_file.directory[i].size.
On line 361, length=icon_file.directory[i].size; sets the value of `length` to the value stored in icon_file.directory[i].size:
On line 362, png=(unsigned char *) AcquireQuantumMemory(length+16,sizeof(*png)); adds 16 to length and allocates that amount of *png structures.

However, if length+16 overflows (for example, length == 2^32 - 15), it will only allocate memory for a single *png.
This is a problem, because the following lines assume that at least 16 bytes was allocated:

(void) CopyMagickMemory(png,"\211PNG\r\n\032\n\000\000\000\015",12);
png[12]=(unsigned char) icon_info.planes;
png[13]=(unsigned char) (icon_info.planes >> 8);
png[14]=(unsigned char) icon_info.bits_per_pixel;
png[15]=(unsigned char) (icon_info.bits_per_pixel >> 8);

And then the following line has a call to ReadBlob, and since length-16 will underflow (and the length is treated as a size_t), it will effectively execute a strcpy with the remaining data in the image file.

count=ReadBlob(image,length-16,png+16);

Stack traces:

Ubuntu release (v6.8.9.9):
Error: lt-convert: malloc.c:3530: _int_malloc: Assertion `(fwd->size & 0x4) == 0' failed.

user@ubuntu15:~$ libtool execute gdb ~/Downloads/imagemagick-6.8.9.9/utilities/convert

gdb$ r corruption.ico /dev/null
Starting program: /home/user/Downloads/imagemagick-6.8.9.9/utilities/.libs/lt-convert corruption.ico /dev/null
[Thread debugging using libthread_db enabled]
Using host libthread_db library "/lib/i386-linux-gnu/libthread_db.so.1".
lt-convert: malloc.c:3530: _int_malloc: Assertion `(fwd->size & 0x4) == 0' failed.
[New Thread 0xb4b89b40 (LWP 27859)]

Program received signal SIGABRT, Aborted.
--------------------------------------------------------------------------[regs]
  EAX: 0x00000000 EBX: 0x00006CCF ECX: 0x00006CCF EDX: 0x00000006 o d I t s z a P c
  ESI: 0xB78B88A6 EDI: 0xB790F000 EBP: 0xB78B761C ESP: 0xBFFF2514 EIP: 0xB7FDBBE0
  CS: 0073 DS: 007B ES: 007B FS: 0000 GS: 0033 SS: 007B
--------------------------------------------------------------------------[code]
=> 0xb7fdbbe0 <__kernel_vsyscall+16>: pop ebp
   0xb7fdbbe1 <__kernel_vsyscall+17>: pop edx
   0xb7fdbbe2 <__kernel_vsyscall+18>: pop ecx
   0xb7fdbbe3 <__kernel_vsyscall+19>: ret
   0xb7fdbbe4: int3
   0xb7fdbbe5: cli
   0xb7fdbbe6: (bad)
   0xb7fdbbe7: call DWORD PTR [eax+eax*1]
--------------------------------------------------------------------------------
0xb7fdbbe0 in __kernel_vsyscall ()
gdb$ bt
#0 0xffffffff in __kernel_vsyscall ()
#1 0xffffffff in __GI_raise (sig=0x6) at ../sysdeps/unix/sysv/linux/raise.c:55
#2 0xffffffff in __GI_abort () at abort.c:89
#3 0xffffffff in __malloc_assert (assertion=assertion@entry=0xb78b863b "(fwd->size & 0x4) == 0", file=file@entry=0xb78b850b "malloc.c", line=0xdca, function=0xb78b88a6 <__func__.11176> "_int_malloc") at malloc.c:297
#4 0xffffffff in _int_malloc (av=av@entry=0xb790f840 <main_arena>, bytes=bytes@entry=0x4104) at malloc.c:3530
#5 0xffffffff in __GI___libc_malloc (bytes=0x4104) at malloc.c:2895
#6 0xffffffff in AcquireMagickMemory (size=0x4104) at magick/memory.c:464
#7 0xffffffff in AcquireImageInfo () at magick/image.c:334
#8 0xffffffff in CloneImageInfo (image_info=0x805e458) at magick/image.c:939
#9 0xffffffff in ReadICONImage (image_info=0x805e458, exception=0x80538d8) at coders/icon.c:362
#10 0xffffffff in ReadImage (image_info=0x805a350, exception=0x80538d8) at magick/constitute.c:547
#11 0xffffffff in ReadImages (image_info=0x805a350, exception=0x80538d8) at magick/constitute.c:853
#12 0xffffffff in ConvertImageCommand (image_info=0x2, argc=0x3, argv=0x8054ce8, metadata=0x0, exception=0x80538d8) at wand/convert.c:622
#13 0xffffffff in MagickCommandGenesis (image_info=0x8056248, command=0x8048620 <ConvertImageCommand@plt>, argc=0x3, argv=0xbffff054, metadata=0x0, exception=0x80538d8) at wand/mogrify.c:168
#14 0x080486ec in main (argv=0xbffff054, argc=<optimized out>) at utilities/convert.c:81
#15 0x080486ec in main (argc=0x3, argv=0xbffff054) at utilities/convert.c:92

Newest release: Version 6.9.1-3
Error: *** Error in `/home/user/Desktop/ImageMagick-6.9.1-3/utilities/.libs/lt-convert': corrupted double-linked list: 0x080833f8 ***

gdb$ r corruption.ico /dev/null
Starting program: /home/user/Desktop/ImageMagick-6.9.1-3/utilities/.libs/lt-convert corruption.ico /dev/null
[Thread debugging using libthread_db enabled]
Using host libthread_db library "/lib/i386-linux-gnu/libthread_db.so.1".
*** Error in `/home/user/Desktop/ImageMagick-6.9.1-3/utilities/.libs/lt-convert': corrupted double-linked list: 0x080833f8 ***
[New Thread 0xb4b95b40 (LWP 27765)]

Program received signal SIGABRT, Aborted.
--------------------------------------------------------------------------[regs]
  EAX: 0x00000000 EBX: 0x00006C71 ECX: 0x00006C71 EDX: 0x00000006 o d I t s z a P c
  ESI: 0x0000007F EDI: 0xB78F0000 EBP: 0xBFFF2608 ESP: 0xBFFF2344 EIP: 0xB7FDBBE0
  CS: 0073 DS: 007B ES: 007B FS: 0000 GS: 0033 SS: 007B
--------------------------------------------------------------------------[code]
=> 0xb7fdbbe0 <__kernel_vsyscall+16>: pop ebp
   0xb7fdbbe1 <__kernel_vsyscall+17>: pop edx
   0xb7fdbbe2 <__kernel_vsyscall+18>: pop ecx
   0xb7fdbbe3 <__kernel_vsyscall+19>: ret
   0xb7fdbbe4: int3
   0xb7fdbbe5: cli
   0xb7fdbbe6: (bad)
   0xb7fdbbe7: call DWORD PTR [eax+eax*1]
--------------------------------------------------------------------------------
0xb7fdbbe0 in __kernel_vsyscall ()
gdb$ bt
#0 0xffffffff in __kernel_vsyscall ()
#1 0xffffffff in __GI_raise (sig=0x6) at ../sysdeps/unix/sysv/linux/raise.c:55
#2 0xffffffff in __GI_abort () at abort.c:89
#3 0xffffffff in __libc_message (do_abort=0x1, fmt=0xb789d444 "*** Error in `%s': %s: 0x%s ***\n") at ../sysdeps/posix/libc_fatal.c:175
#4 0xffffffff in malloc_printerr (action=<optimized out>, str=0xb7899549 "corrupted double-linked list", ptr=0x80833f8) at malloc.c:4965
#5 0xffffffff in malloc_consolidate (av=av@entry=0xb78f0840 <main_arena>) at malloc.c:4142
#6 0xffffffff in _int_malloc (av=av@entry=0xb78f0840 <main_arena>, bytes=bytes@entry=0x4104) at malloc.c:3417
#7 0xffffffff in __GI___libc_malloc (bytes=0x4104) at malloc.c:2895
#8 0xffffffff in AcquireMagickMemory (size=0x4104) at magick/memory.c:464
#9 0xffffffff in AcquireImageInfo () at magick/image.c:334
#10 0xffffffff in CloneImageInfo (image_info=0x8061980) at magick/image.c:939
#11 0xffffffff in ReadICONImage (image_info=0x8061980, exception=0x80535d8) at coders/icon.c:384
#12 0xffffffff in ReadImage (image_info=0x805d878, exception=0x80535d8) at magick/constitute.c:547
#13 0xffffffff in ReadImages (image_info=0x8059590, exception=0x80535d8) at magick/constitute.c:851
#14 0xffffffff in ConvertImageCommand (image_info=0x2, argc=0x3, argv=0x8054d28, metadata=0x0, exception=0x80535d8) at wand/convert.c:622
#15 0xffffffff in MagickCommandGenesis (image_info=0x8055488, command=0x8048620 <ConvertImageCommand@plt>, argc=0x3, argv=0xbffff054, metadata=0x0, exception=0x80535d8) at wand/mogrify.c:168
#16 0x080486ec in main (argv=0xbffff054, argc=<optimized out>) at utilities/convert.c:81
#17 0x080486ec in main (argc=0x3, argv=0xbffff054) at utilities/convert.c:92

Moshe Kaplan (moshekaplan) wrote :

Including file that triggers the issue

Moshe Kaplan (moshekaplan) wrote :

Reported this issue to the ImageMagick project by filling the form at http://www.imagemagick.org/script/contact.php

Changed in imagemagick (Ubuntu):
status: New → Confirmed
Moshe Kaplan (moshekaplan) wrote :

Would it be possible to have a CVE number assigned for this vulnerability?

information type: Private Security → Public Security
Raphaël Hertzog (hertzog) wrote :

That bug only works on 32 bit systems because ReadBlobLSBLong() reads 4 bytes and returns an "unsigned int" which is then stored in a "size_t" (the length variable) which is usually 64 bit on 64 bit systems. So length+14 does not overflow and the huge memory allocation simply fails.

Note that old versions of ImageMagick added 12 and not 16 to the length so that the sample corruption.ico also doesn't work to reproduce the bug in old versions (I looked at 6.6.0.4 for the needs of Debian Squeeze). Attached is another version of the file that should work on such versions.

Launchpad Janitor (janitor) wrote :

This bug was fixed in the package imagemagick - 8:6.8.9.9-7

---------------
imagemagick (8:6.8.9.9-7) unstable; urgency=low

  * Fix various minor security issues
    - Fix an integer overflow that can lead to a buffer overrun
      in the icon parsing code (LP: #1459747, closes: #806441)
    - Fix an integer overflow that can lead to a double free in
      pict parsing (LP: #1448803, closes: #806441).
    - Memory Leak while handle psd file (closes: #811308)
      http://www.imagemagick.org/discourse-server/viewtopic.php?f=3&t=28791
    - IM 6.9.2 crash with some PNG (closes: #811308, LP: #1492881)
      http://www.imagemagick.org/discourse-server/viewtopic.php?f=3&t=28466
    - Null pointer access in magick/constitute.c (closes: #811308)
      https://github.com/ImageMagick/ImageMagick/pull/34
    - PixelColor off by one on i386 (closes: #811308)
      https://github.com/ImageMagick/ImageMagick/issues/54
    - Fixed other memory leaks (closes: #811308)

 -- Vincent Fourmond <email address hidden> Sun, 17 Jan 2016 21:18:19 +0100

Changed in imagemagick (Ubuntu):
status: Confirmed → Fix Released
To post a comment you must log in.
This report contains Public Security information  Edit
Everyone can see this security related information.

Other bug subscribers