Bug 1465061 - There is an invalid free in Image::printIFDStructure that leads to a Segmentation fault at exiv2. A crafted input will lead to remote denial of service attack.
There is an invalid free in Image::printIFDStructure that leads to a Segmenta...
Status: NEW
Product: Red Hat Enterprise Linux 7
Classification: Red Hat
Component: exiv2 (Show other bugs)
7.5-Alt
x86_64 Linux
unspecified Severity urgent
: rc
: ---
Assigned To: Jan Grulich
Desktop QE
:
Depends On:
Blocks:
  Show dependency treegraph
 
Reported: 2017-06-26 10:09 EDT by owl337
Modified: 2017-10-29 19:49 EDT (History)
2 users (show)

See Also:
Fixed In Version:
Doc Type: If docs needed, set a value
Doc Text:
Story Points: ---
Clone Of:
Environment:
Last Closed:
Type: Bug
Regression: ---
Mount Type: ---
Documentation: ---
CRM:
Verified Versions:
Category: ---
oVirt Team: ---
RHEL 7.3 requirements from Atomic Host:
Cloudforms Team: ---


Attachments (Terms of Use)
Triggered by "exiv POC1" (93 bytes, application/x-rar)
2017-06-26 10:09 EDT, owl337
no flags Details

  None (edit)
Description owl337 2017-06-26 10:09:44 EDT
Created attachment 1291986 [details]
Triggered by  "exiv POC1"

Description of problem:

There is an ivalid free in Image::printIFDStructure that leads to a Segmentation fault at exiv2. A crafted input will lead to remote denial of service attack.

Version-Release number of selected component (if applicable):

<= 0.26

How reproducible:

exiv2 POC1


Steps to Reproduce:

$./exiv2 POC1

invalid type value detected in Image::printIFDStructure:  32768
Exiv2  exception in print action for file POC1:
invalid type value detected in Image::printIFDStructure
Segmentation fault

The gdb debugging information is as follows:

(gdb) set args POC1
(gdb) r
...
invalid type value detected in Image::printIFDStructure

Program received signal SIGSEGV, Segmentation fault.
__GI___libc_free (mem=0x656400) at malloc.c:2933
2933	malloc.c: No such file or directory.
(gdb) bt
#0  __GI___libc_free (mem=0x656400) at malloc.c:2933
#1  0x00007ffff745b823 in __gnu_cxx::new_allocator<char>::deallocate (
    __p=0x656400 <error: Cannot access memory at address 0x656400>, this=<optimized out>)
    at /usr/bin/../lib/gcc/x86_64-linux-gnu/5.2.1/../../../../include/c++/5.2.1/ext/new_allocator.h:110
#2  __gnu_cxx::__alloc_traits<std::allocator<char> >::deallocate (
    __p=0x656400 <error: Cannot access memory at address 0x656400>, __a=..., __n=<optimized out>)
    at /usr/bin/../lib/gcc/x86_64-linux-gnu/5.2.1/../../../../include/c++/5.2.1/ext/alloc_traits.h:185
#3  std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >::_M_destroy (this=<optimized out>, 
    __size=<optimized out>)
    at /usr/bin/../lib/gcc/x86_64-linux-gnu/5.2.1/../../../../include/c++/5.2.1/bits/basic_string.h:185
#4  std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >::_M_dispose (this=<optimized out>)
    at /usr/bin/../lib/gcc/x86_64-linux-gnu/5.2.1/../../../../include/c++/5.2.1/bits/basic_string.h:180
#5  std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >::~basic_string (
    this=<optimized out>)
    at /usr/bin/../lib/gcc/x86_64-linux-gnu/5.2.1/../../../../include/c++/5.2.1/bits/basic_string.h:544
#6  std::pair<int const, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >::~pair (
    this=<optimized out>) at /usr/bin/../lib/gcc/x86_64-linux-gnu/5.2.1/../../../../include/c++/5.2.1/bits/stl_pair.h:96
#7  __gnu_cxx::new_allocator<std::pair<int const, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > > >::destroy (this=<optimized out>, __p=<optimized out>)
    at /usr/bin/../lib/gcc/x86_64-linux-gnu/5.2.1/../../../../include/c++/5.2.1/ext/new_allocator.h:133
#8  std::_Rb_tree<int, std::pair<int const, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >, std::_Select1st<std::pair<int const, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > > >, std::less<int>, std::allocator<std::pair<int const, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > > > >::_M_destroy_node (this=0x7ffff79a0818 <Exiv2::tagName(unsigned short, unsigned long)::tags>, 
---Type <return> to continue, or q <return> to quit---
    __p=0x0) at /usr/bin/../lib/gcc/x86_64-linux-gnu/5.2.1/../../../../include/c++/5.2.1/bits/stl_tree.h:520
#9  std::_Rb_tree<int, std::pair<int const, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >, std::_Select1st<std::pair<int const, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > > >, std::less<int>, std::allocator<std::pair<int const, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > > > >::_M_drop_node (this=0x7ffff79a0818 <Exiv2::tagName(unsigned short, unsigned long)::tags>, 
    __p=0x0) at /usr/bin/../lib/gcc/x86_64-linux-gnu/5.2.1/../../../../include/c++/5.2.1/bits/stl_tree.h:561
#10 std::_Rb_tree<int, std::pair<int const, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >, std::_Select1st<std::pair<int const, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > > >, std::less<int>, std::allocator<std::pair<int const, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > > > >::_M_erase (this=0x7ffff79a0818 <Exiv2::tagName(unsigned short, unsigned long)::tags>, __x=0x0)
    at /usr/bin/../lib/gcc/x86_64-linux-gnu/5.2.1/../../../../include/c++/5.2.1/bits/stl_tree.h:1614
#11 0x00007ffff745b7e3 in std::_Rb_tree<int, std::pair<int const, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >, std::_Select1st<std::pair<int const, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > > >, std::less<int>, std::allocator<std::pair<int const, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > > > >::_M_erase (
    this=0x7ffff79a0818 <Exiv2::tagName(unsigned short, unsigned long)::tags>, __x=<optimized out>)
    at /usr/bin/../lib/gcc/x86_64-linux-gnu/5.2.1/../../../../include/c++/5.2.1/bits/stl_tree.h:1612
#12 0x00007ffff745b7e3 in std::_Rb_tree<int, std::pair<int const, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >, std::_Select1st<std::pair<int const, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > > >, std::less<int>, std::allocator<std::pair<int const, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > > > >::_M_erase (
    this=0x7ffff79a0818 <Exiv2::tagName(unsigned short, unsigned long)::tags>, __x=<optimized out>)
    at /usr/bin/../lib/gcc/x86_64-linux-gnu/5.2.1/../../../../include/c++/5.2.1/bits/stl_tree.h:1612
#13 0x00007ffff745b7e3 in std::_Rb_tree<int, std::pair<int const, std::__cxx11::basic_string<char, std::char_traits<char>---Type <return> to continue, or q <return> to quit---
, std::allocator<char> > >, std::_Select1st<std::pair<int const, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > > >, std::less<int>, std::allocator<std::pair<int const, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > > > >::_M_erase (
    this=0x7ffff79a0818 <Exiv2::tagName(unsigned short, unsigned long)::tags>, __x=<optimized out>)
    at /usr/bin/../lib/gcc/x86_64-linux-gnu/5.2.1/../../../../include/c++/5.2.1/bits/stl_tree.h:1612
#14 0x00007ffff745b7e3 in std::_Rb_tree<int, std::pair<int const, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >, std::_Select1st<std::pair<int const, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > > >, std::less<int>, std::allocator<std::pair<int const, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > > > >::_M_erase (
    this=0x7ffff79a0818 <Exiv2::tagName(unsigned short, unsigned long)::tags>, __x=<optimized out>)
    at /usr/bin/../lib/gcc/x86_64-linux-gnu/5.2.1/../../../../include/c++/5.2.1/bits/stl_tree.h:1612
#15 0x00007ffff745b7e3 in std::_Rb_tree<int, std::pair<int const, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >, std::_Select1st<std::pair<int const, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > > >, std::less<int>, std::allocator<std::pair<int const, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > > > >::_M_erase (
    this=0x7ffff79a0818 <Exiv2::tagName(unsigned short, unsigned long)::tags>, __x=<optimized out>)
    at /usr/bin/../lib/gcc/x86_64-linux-gnu/5.2.1/../../../../include/c++/5.2.1/bits/stl_tree.h:1612
#16 0x00007ffff6694c92 in __run_exit_handlers (status=1, listp=0x7ffff6a1f698 <__exit_funcs>, 
    run_list_atexit=run_list_atexit@entry=true) at exit.c:82
#17 0x00007ffff6694ce5 in __GI_exit (status=<optimized out>) at exit.c:104
#18 0x00007ffff667bac7 in __libc_start_main (main=0x407240 <main(int, char* const*)>, argc=2, argv=0x7fffffffe538, 
    init=<optimized out>, fini=<optimized out>, rtld_fini=<optimized out>, stack_end=0x7fffffffe528) at libc-start.c:323
#19 0x0000000000407169 in _start ()

This vulnerability was triggered in __GI___libc_free() at line malloc.c:2933. From the information above we can see that the program try to free a memory it can not access. In order to get more information, we use AddressSanitizer mode compiling the program . 

$ ./exiv2 POC1
invalid type value detected in Image::printIFDStructure:  32768
Exiv2 exception in print action for file POC1:
invalid type value detected in Image::printIFDStructure
=================================================================
==28127==ERROR: AddressSanitizer: attempting free on address which was not malloc()-ed: 0x60200000ed90 in thread T0
    #0 0x4e1c92  (/home/icy/real/exiv2-asan/install/bin/exiv2+0x4e1c92)
    #1 0x51515c  (/home/icy/real/exiv2-asan/install/bin/exiv2+0x51515c)
    #2 0x4e2fe6  (/home/icy/real/exiv2-asan/install/bin/exiv2+0x4e2fe6)
    #3 0x7f057e3ffabf  (/lib/x86_64-linux-gnu/libc.so.6+0x20abf)
    #4 0x43b288  (/home/icy/real/exiv2-asan/install/bin/exiv2+0x43b288)

AddressSanitizer can not describe address in more detail (wild memory access suspected).
==28127==ABORTING


Actual results:

crash

Expected results:

crash


Additional info:

Credits:

This vulnerability is detected by team OWL337, with our custom fuzzer collAFL. Please contact ganshuitao@gmail.com   and chaoz@tsinghua.edu.cn if you need more info about the team, the tool or the vulnerability.
Comment 2 dan.cermak 2017-10-29 19:49:36 EDT
The upstream issue is: https://github.com/Exiv2/exiv2/issues/144. The issue has been fixed on the master branch.

Note You need to log in before you can comment on or make changes to this bug.