Headline
CVE-2019-14370: heap-buffer-overflow in Exiv2::MrwImage::readMetadata() · Issue #954 · Exiv2/exiv2
In Exiv2 0.27.99.0, there is an out-of-bounds read in Exiv2::MrwImage::readMetadata() in mrwimage.cpp. It could result in denial of service.
Describe the bug
in my research , a heap overflow found in Exiv2::MrwImage::readMetadata() /home/tim/exiv2-asan/src/mrwimage.cpp:131.
To Reproduce
exiv2 -pv $poc
poc1.zip
Expected behavior
asan output
rASAN:DEADLYSIGNAL
=================================================================
==45838==ERROR: AddressSanitizer: SEGV on unknown address 0x6030ededef5d (pc 0x7f7971f0157e bp 0x7fffb45f5a30 sp 0x7fffb45f5198 T0)
==45838==The signal is caused by a READ memory access.
#0 0x7f7971f0157d (/lib/x86_64-linux-gnu/libc.so.6+0xbb57d)
#1 0x7f79734236ce (/usr/lib/x86_64-linux-gnu/libasan.so.4+0x796ce)
#2 0x7f79729be723 in memcpy /usr/include/x86_64-linux-gnu/bits/string_fortified.h:34
#3 0x7f79729be723 in Exiv2::MemIo::read(unsigned char*, unsigned long) /home/tim/exiv2-asan/src/basicio.cpp:1354
#4 0x7f7972aff426 in Exiv2::MrwImage::readMetadata() /home/tim/exiv2-asan/src/mrwimage.cpp:131
#5 0x7f7972b09a9c in Exiv2::PgfImage::readMetadata() /home/tim/exiv2-asan/src/pgfimage.cpp:153
#6 0x55ab241e8644 in Action::Print::printSummary() /home/tim/exiv2-asan/src/actions.cpp:260
#7 0x55ab241ed304 in Action::Print::run(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&) /home/tim/exiv2-asan/src/actions.cpp:215
#8 0x55ab24165692 in main /home/tim/exiv2-asan/src/exiv2.cpp:77
#9 0x7f7971e67b96 in __libc_start_main (/lib/x86_64-linux-gnu/libc.so.6+0x21b96)
#10 0x55ab24166359 in _start (/home/tim/exiv2-asan/build/bin/exiv2+0x18359)
AddressSanitizer can not provide additional info.
SUMMARY: AddressSanitizer: SEGV (/lib/x86_64-linux-gnu/libc.so.6+0xbb57d)
==45838==ABORTING
gdb output
gdb-peda$ r /home/tim/poc1
Starting program: /home/tim/fuzz/exiv2/exiv2 /home/tim/poc1
[Thread debugging using libthread_db enabled]
Using host libthread_db library "/lib/x86_64-linux-gnu/libthread_db.so.1".
Program received signal SIGSEGV, Segmentation fault.
[----------------------------------registers-----------------------------------]
RAX: 0x7fffffffdf60 --> 0xedededededededed
RBX: 0xffffffff12121221
RCX: 0xedededededededed
RDX: 0x8
RSI: 0x55564368c1dd
RDI: 0x7fffffffdf60 --> 0xedededededededed
RBP: 0x8
RSP: 0x7fffffffdec8 --> 0x7ffff79796bf (<Exiv2::MemIo::read(unsigned char*, unsigned long)+63>: mov rax,QWORD PTR [r13+0x10])
RIP: 0x7ffff70d1b53 (<__memmove_avx_unaligned_erms+131>: mov rcx,QWORD PTR [rsi+rdx*1-0x8])
R8 : 0x5555557ad3a0 --> 0x7ffff7db10d0 (:MemIo+16>: 0x00007ffff7974450)
R9 : 0x0
R10: 0xa ('\n')
R11: 0x7ffff79fa3d0 (<Exiv2::getULong(unsigned char const*, Exiv2::ByteOrder)>: mov eax,DWORD PTR [rdi])
R12: 0x8
R13: 0x5555557ad3a0 --> 0x7ffff7db10d0 (:MemIo+16>: 0x00007ffff7974450)
R14: 0x7fffffffdf61 --> 0xededededededed
R15: 0x7ffff7db1438 (:IoCloser>: 0x0000000000000000)
EFLAGS: 0x10246 (carry PARITY adjust ZERO sign trap INTERRUPT direction overflow)
[-------------------------------------code-------------------------------------]
0x7ffff70d1b48 <__memmove_avx_unaligned_erms+120>: vmovdqu XMMWORD PTR [rdi],xmm0
0x7ffff70d1b4c <__memmove_avx_unaligned_erms+124>: vmovdqu XMMWORD PTR [rdi+rdx*1-0x10],xmm1
0x7ffff70d1b52 <__memmove_avx_unaligned_erms+130>: ret
=> 0x7ffff70d1b53 <__memmove_avx_unaligned_erms+131>: mov rcx,QWORD PTR [rsi+rdx*1-0x8]
0x7ffff70d1b58 <__memmove_avx_unaligned_erms+136>: mov rsi,QWORD PTR [rsi]
0x7ffff70d1b5b <__memmove_avx_unaligned_erms+139>: mov QWORD PTR [rdi+rdx*1-0x8],rcx
0x7ffff70d1b60 <__memmove_avx_unaligned_erms+144>: mov QWORD PTR [rdi],rsi
0x7ffff70d1b63 <__memmove_avx_unaligned_erms+147>: ret
[------------------------------------stack-------------------------------------]
0000| 0x7fffffffdec8 --> 0x7ffff79796bf (<Exiv2::MemIo::read(unsigned char*, unsigned long)+63>: mov rax,QWORD PTR [r13+0x10])
0008| 0x7fffffffded0 --> 0x7ffff7db1438 (:IoCloser>: 0x0000000000000000)
0016| 0x7fffffffded8 --> 0x5555557aca60 --> 0x7ffff7db22f8 (:MrwImage+16>: 0x00007ffff79d4f90)
0024| 0x7fffffffdee0 --> 0xededee05
0032| 0x7fffffffdee8 --> 0x7fffffffdf60 --> 0xedededededededed
0040| 0x7fffffffdef0 --> 0xf7ffffff
0048| 0x7fffffffdef8 --> 0x7ffff79d471b (<Exiv2::MrwImage::readMetadata()+603>: mov rdi,QWORD PTR [rbx+0x8])
0056| 0x7fffffffdf00 --> 0x7ffff7db1448 (:IoCloser+16>: 0x00007ffff7988490)
[------------------------------------------------------------------------------]
Legend: code, data, rodata, value
Stopped reason: SIGSEGV
__memmove_avx_unaligned_erms () at ../sysdeps/x86_64/multiarch/memmove-vec-unaligned-erms.S:299
299 ../sysdeps/x86_64/multiarch/memmove-vec-unaligned-erms.S: No such file or directory.
gdb-peda$ bt
#0 __memmove_avx_unaligned_erms () at ../sysdeps/x86_64/multiarch/memmove-vec-unaligned-erms.S:299
#1 0x00007ffff79796bf in memcpy (__len=<optimized out>, __src=<optimized out>, __dest=<optimized out>) at /usr/include/x86_64-linux-gnu/bits/string_fortified.h:34
#2 Exiv2::MemIo::read (this=0x5555557ad3a0, buf=<optimized out>, rcount=0x8) at /home/tim/exiv2/src/basicio.cpp:1354
#3 0x00007ffff79d471b in Exiv2::MrwImage::readMetadata (this=0x5555557aca60) at /home/tim/exiv2/src/mrwimage.cpp:131
#4 0x00007ffff79d7d82 in Exiv2::PgfImage::readMetadata (this=0x5555557ac920) at /home/tim/exiv2/src/pgfimage.cpp:153
#5 0x000055555557f40d in Action::Print::printSummary (this=0x5555557ada50) at /home/tim/exiv2/src/actions.cpp:260
#6 0x00005555555808c5 in Action::Print::run (this=0x5555557ada50, path="/home/tim/poc1") at /home/tim/exiv2/src/actions.cpp:215
#7 0x000055555555e304 in main (argc=argc@entry=0x2, argv=argv@entry=0x7fffffffe578) at /home/tim/exiv2/src/exiv2.cpp:77
#8 0x00007ffff6f64b97 in __libc_start_main (main=0x55555555e100 <main(int, char* const*)>, argc=0x2, argv=0x7fffffffe578, init=<optimized out>, fini=<optimized out>, rtld_fini=<optimized out>, stack_end=0x7fffffffe568) at ../csu/libc-start.c:310
#9 0x000055555555e6da in _start ()
gdb-peda$ vmmap
Start End Perm Name
0x0000555555554000 0x0000555555597000 r-xp /home/tim/fuzz/exiv2/exiv2
0x0000555555796000 0x0000555555798000 r--p /home/tim/fuzz/exiv2/exiv2
0x0000555555798000 0x0000555555799000 rw-p /home/tim/fuzz/exiv2/exiv2
0x0000555555799000 0x00005555557ba000 rw-p [heap]
0x00007ffff5b67000 0x00007ffff6536000 r--p /usr/lib/locale/locale-archive
0x00007ffff6536000 0x00007ffff66d3000 r-xp /lib/x86_64-linux-gnu/libm-2.27.so
0x00007ffff66d3000 0x00007ffff68d2000 ---p /lib/x86_64-linux-gnu/libm-2.27.so
0x00007ffff68d2000 0x00007ffff68d3000 r--p /lib/x86_64-linux-gnu/libm-2.27.so
0x00007ffff68d3000 0x00007ffff68d4000 rw-p /lib/x86_64-linux-gnu/libm-2.27.so
0x00007ffff68d4000 0x00007ffff68ee000 r-xp /lib/x86_64-linux-gnu/libpthread-2.27.so
0x00007ffff68ee000 0x00007ffff6aed000 ---p /lib/x86_64-linux-gnu/libpthread-2.27.so
0x00007ffff6aed000 0x00007ffff6aee000 r--p /lib/x86_64-linux-gnu/libpthread-2.27.so
0x00007ffff6aee000 0x00007ffff6aef000 rw-p /lib/x86_64-linux-gnu/libpthread-2.27.so
0x00007ffff6aef000 0x00007ffff6af3000 rw-p mapped
0x00007ffff6af3000 0x00007ffff6b22000 r-xp /lib/x86_64-linux-gnu/libexpat.so.1.6.7
0x00007ffff6b22000 0x00007ffff6d22000 ---p /lib/x86_64-linux-gnu/libexpat.so.1.6.7
0x00007ffff6d22000 0x00007ffff6d24000 r--p /lib/x86_64-linux-gnu/libexpat.so.1.6.7
0x00007ffff6d24000 0x00007ffff6d25000 rw-p /lib/x86_64-linux-gnu/libexpat.so.1.6.7
0x00007ffff6d25000 0x00007ffff6d41000 r-xp /usr/local/lib/libz.so.1.2.11
0x00007ffff6d41000 0x00007ffff6f41000 ---p /usr/local/lib/libz.so.1.2.11
0x00007ffff6f41000 0x00007ffff6f42000 r--p /usr/local/lib/libz.so.1.2.11
0x00007ffff6f42000 0x00007ffff6f43000 rw-p /usr/local/lib/libz.so.1.2.11
0x00007ffff6f43000 0x00007ffff712a000 r-xp /lib/x86_64-linux-gnu/libc-2.27.so
0x00007ffff712a000 0x00007ffff732a000 ---p /lib/x86_64-linux-gnu/libc-2.27.so
0x00007ffff732a000 0x00007ffff732e000 r--p /lib/x86_64-linux-gnu/libc-2.27.so
0x00007ffff732e000 0x00007ffff7330000 rw-p /lib/x86_64-linux-gnu/libc-2.27.so
0x00007ffff7330000 0x00007ffff7334000 rw-p mapped
0x00007ffff7334000 0x00007ffff734b000 r-xp /lib/x86_64-linux-gnu/libgcc_s.so.1
0x00007ffff734b000 0x00007ffff754a000 ---p /lib/x86_64-linux-gnu/libgcc_s.so.1
0x00007ffff754a000 0x00007ffff754b000 r--p /lib/x86_64-linux-gnu/libgcc_s.so.1
0x00007ffff754b000 0x00007ffff754c000 rw-p /lib/x86_64-linux-gnu/libgcc_s.so.1
0x00007ffff754c000 0x00007ffff76c5000 r-xp /usr/lib/x86_64-linux-gnu/libstdc++.so.6.0.25
0x00007ffff76c5000 0x00007ffff78c5000 ---p /usr/lib/x86_64-linux-gnu/libstdc++.so.6.0.25
0x00007ffff78c5000 0x00007ffff78cf000 r--p /usr/lib/x86_64-linux-gnu/libstdc++.so.6.0.25
0x00007ffff78cf000 0x00007ffff78d1000 rw-p /usr/lib/x86_64-linux-gnu/libstdc++.so.6.0.25
0x00007ffff78d1000 0x00007ffff78d5000 rw-p mapped
0x00007ffff78d5000 0x00007ffff7b86000 r-xp /home/tim/exiv2/build/lib/libexiv2.so.0.27.99.0
0x00007ffff7b86000 0x00007ffff7d85000 ---p /home/tim/exiv2/build/lib/libexiv2.so.0.27.99.0
0x00007ffff7d85000 0x00007ffff7db7000 r--p /home/tim/exiv2/build/lib/libexiv2.so.0.27.99.0
0x00007ffff7db7000 0x00007ffff7dba000 rw-p /home/tim/exiv2/build/lib/libexiv2.so.0.27.99.0
0x00007ffff7dba000 0x00007ffff7dd5000 rw-p mapped
0x00007ffff7dd5000 0x00007ffff7dfc000 r-xp /lib/x86_64-linux-gnu/ld-2.27.so
0x00007ffff7fda000 0x00007ffff7fe0000 rw-p mapped
0x00007ffff7ff5000 0x00007ffff7ff7000 rw-p mapped
0x00007ffff7ff7000 0x00007ffff7ffa000 r--p [vvar]
0x00007ffff7ffa000 0x00007ffff7ffc000 r-xp [vdso]
0x00007ffff7ffc000 0x00007ffff7ffd000 r--p /lib/x86_64-linux-gnu/ld-2.27.so
0x00007ffff7ffd000 0x00007ffff7ffe000 rw-p /lib/x86_64-linux-gnu/ld-2.27.so
0x00007ffff7ffe000 0x00007ffff7fff000 rw-p mapped
0x00007ffffffde000 0x00007ffffffff000 rw-p [stack]
0xffffffffff600000 0xffffffffff601000 r-xp [vsyscall]
Desktop (please complete the following information):
- ubuntu18
- gcc 7.4.0
- -fsanitize=address -g