Closed
Description
Hello all.
We found a denial of service (DoS) issue in ImageMagick 7.0.7-12 Q16 x86_64 , which can cause huge CPU consumption. (cpu 100%)
The policy.xml is as following
<policymap>
<policy domain="resource" name="temporary-path" value="/tmp"/>
<policy domain="resource" name="memory" value="256MiB"/>
<policy domain="resource" name="map" value="512MiB"/>
<policy domain="resource" name="width" value="8KP"/>
<policy domain="resource" name="height" value="8KP"/>
<policy domain="resource" name="area" value="16KP"/>
<policy domain="resource" name="disk" value="1GiB"/>
<policy domain="resource" name="file" value="768"/>
<policy domain="resource" name="thread" value="2"/>
<policy domain="resource" name="throttle" value="0"/>
<policy domain="resource" name="time" value="120"/>
<policy domain="system" name="precision" value="6"/>
<policy domain="coder" rights="none" pattern="MVG" />
<policy domain="filter" rights="none" pattern="*" />
<policy domain="delegate" rights="none" pattern="HTTPS" />
<policy domain="path" rights="none" pattern="@*"/>
</policymap>
convert SeekBlob-cpu-exhaustion /dev/null
gdb backtrace
(gdb) bt
#0 0x00007ffff6ef1330 in __read_nocancel () at ../sysdeps/unix/syscall-template.S:81
#1 0x00007ffff6e7abe9 in _IO_new_file_seekoff (fp=0x63ff40, offset=238935896, dir=<optimized out>, mode=3) at fileops.c:1079
#2 0x00007ffff6e748c7 in fseeko (fp=0x63ff40, offset=offset@entry=8, whence=whence@entry=1) at fseeko.c:39
#3 0x00007ffff779b1d2 in SeekBlob (image=image@entry=0x6366b0, offset=offset@entry=8, whence=whence@entry=1) at MagickCore/blob.c:4627
#4 0x00007ffff794e964 in SkipDXTMipmaps (image=0x6366b0, dds_info=0x7fffffff45e0, texel_size=8, exception=<optimized out>) at coders/dds.c:2552
#5 0x00007ffff794de03 in ReadDDSImage (image_info=0x61fe10, exception=0x612c90) at coders/dds.c:1830
#6 0x00007ffff77c962f in ReadImage (image_info=image_info@entry=0x61cb20, exception=exception@entry=0x612c90) at MagickCore/constitute.c:555
#7 0x00007ffff77ca64f in ReadImages (image_info=image_info@entry=0x619830, filename=filename@entry=0x611c10 "/tmp/cpu-poc2", exception=exception@entry=0x612c90)
at MagickCore/constitute.c:866
#8 0x00007ffff742dbb3 in ConvertImageCommand (image_info=0x619830, argc=3, argv=0x611b50, metadata=0x7fffffffc180, exception=0x612c90) at MagickWand/convert.c:641
#9 0x00007ffff7499764 in MagickCommandGenesis (image_info=image_info@entry=0x616540, command=command@entry=0x400f50 <ConvertImageCommand@plt>, argc=argc@entry=3,
argv=argv@entry=0x7fffffffe4d8, metadata=0x0, exception=exception@entry=0x612c90) at MagickWand/mogrify.c:183
#10 0x00000000004011cf in MagickMain (argc=3, argv=0x7fffffffe4d8) at utilities/magick.c:149
#11 0x00007ffff6e23f45 in __libc_start_main (main=0x400fd0 <main>, argc=3, argv=0x7fffffffe4d8, init=<optimized out>, fini=<optimized out>, rtld_fini=<optimized out>,
stack_end=0x7fffffffe4c8) at libc-start.c:287
#12 0x0000000000400ffe in _start ()
when debug found dds_info->mipmapcount is very large
2549 for (i = 1; (i < (ssize_t) dds_info->mipmapcount) && w && h; i++) [67/733]
(gdb)
2551 offset=(MagickOffsetType)((w+3)/4)*((h+3)/4)*texel_size;
(gdb)
2552 if (SeekBlob(image,offset,SEEK_CUR) < 0)
(gdb)
2551 offset=(MagickOffsetType)((w+3)/4)*((h+3)/4)*texel_size;
(gdb)
2552 if (SeekBlob(image,offset,SEEK_CUR) < 0)
(gdb)
2551 offset=(MagickOffsetType)((w+3)/4)*((h+3)/4)*texel_size;
(gdb)
2552 if (SeekBlob(image,offset,SEEK_CUR) < 0)
(gdb)
2554 w=DIV2(w);
(gdb)
2555 h=DIV2(h);
(gdb)
2549 for (i = 1; (i < (ssize_t) dds_info->mipmapcount) && w && h; i++)
(gdb)
2551 offset=(MagickOffsetType)((w+3)/4)*((h+3)/4)*texel_size;
(gdb)
2552 if (SeekBlob(image,offset,SEEK_CUR) < 0)
(gdb)
2551 offset=(MagickOffsetType)((w+3)/4)*((h+3)/4)*texel_size;
(gdb)
2552 if (SeekBlob(image,offset,SEEK_CUR) < 0)
(gdb)
2551 offset=(MagickOffsetType)((w+3)/4)*((h+3)/4)*texel_size;
(gdb)
2552 if (SeekBlob(image,offset,SEEK_CUR) < 0)
(gdb)
2554 w=DIV2(w);
(gdb)
2555 h=DIV2(h);
(gdb)
2549 for (i = 1; (i < (ssize_t) dds_info->mipmapcount) && w && h; i++)
(gdb)
2551 offset=(MagickOffsetType)((w+3)/4)*((h+3)/4)*texel_size;
(gdb)
2552 if (SeekBlob(image,offset,SEEK_CUR) < 0)
(gdb)
2551 offset=(MagickOffsetType)((w+3)/4)*((h+3)/4)*texel_size;
(gdb) p dds_info->mipmapcount
$1 = 4289331201
testcase:
https://github.com/henices/pocs/raw/master/SeekBlob--cpu-exhaustion
Credit: NSFocus Security Team <security (at) nsfocus (dot) com>