Project: exiv2 (exiv2/exiv2), language: c++
Vulnerability instance: exiv2.cve-2018-16336
Sanitizer: address

================= Bug Report (1/1) ==================
## Source: GitHub Issue
## URL: https://github.com/Exiv2/exiv2/issues/400
## Description:
Issue: Exiv2/exiv2#400
Title: CVE-2018-16336: AddressSanitizer: 2 heap-buffer-overflow problems  ( Exiv2::Internal::PngChunk::parseTXTChunk() && bool __gnu_cxx::__ops::_Iter_equals_val<char const>::operator()<unsigned char*>(unsigned char*))
State: closed
Created by: Marsman1996
Created at: 2018-08-14 02:17:50+00:00

Issue Body:
Following bugs was found with mem-AFL, which is based on AFL. Mem-AFL is developed by Yanhao(unfuzzable123@gmail.com) & Marsman1996(lqliuyuwei@outlook.com)

both tested in Ubuntu 16.04, 64bit, Exiv2(master ce516ed && v0.26)
`$ exiv2 $POC`

###  POC1

https://github.com/Marsman1996/pocs/blob/master/exiv2/CVE-2018-16336/poc1-heapoverflow
```
./bin/exiv2 ../../poc1-heapoverflow 
=================================================================
==27206==ERROR: AddressSanitizer: heap-buffer-overflow on address 0x60200000ef31 at pc 0x7feaa8b0e155 bp 0x7ffdafb8d0c0 sp 0x7ffdafb8d0b0
READ of size 1 at 0x60200000ef31 thread T0
    #0 0x7feaa8b0e154 in Exiv2::Internal::PngChunk::parseTXTChunk(Exiv2::DataBuf const&, int, Exiv2::Internal::PngChunk::TxtChunkType) /home/marsman/Desktop/crashana/exiv2/exiv2-ce516eddefbebd31749b361a540832f41f9fe5d0/src/pngchunk_int.cpp:140
    #1 0x7feaa8b0d9e7 in Exiv2::Internal::PngChunk::decodeTXTChunk(Exiv2::Image*, Exiv2::DataBuf const&, Exiv2::Internal::PngChunk::TxtChunkType) /home/marsman/Desktop/crashana/exiv2/exiv2-ce516eddefbebd31749b361a540832f41f9fe5d0/src/pngchunk_int.cpp:83
    #2 0x7feaa8a4ddc1 in Exiv2::PngImage::readMetadata() /home/marsman/Desktop/crashana/exiv2/exiv2-ce516eddefbebd31749b361a540832f41f9fe5d0/src/pngimage.cpp:488
    #3 0x43a4b7 in Action::Print::printSummary() /home/marsman/Desktop/crashana/exiv2/exiv2-ce516eddefbebd31749b361a540832f41f9fe5d0/src/actions.cpp:291
    #4 0x439d2f in Action::Print::run(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&) /home/marsman/Desktop/crashana/exiv2/exiv2-ce516eddefbebd31749b361a540832f41f9fe5d0/src/actions.cpp:251
    #5 0x422407 in main /home/marsman/Desktop/crashana/exiv2/exiv2-ce516eddefbebd31749b361a540832f41f9fe5d0/src/exiv2.cpp:166
    #6 0x7feaa7cea82f in __libc_start_main (/lib/x86_64-linux-gnu/libc.so.6+0x2082f)
    #7 0x421e18 in _start (/home/marsman/Desktop/crashana/exiv2/exiv2-ce516eddefbebd31749b361a540832f41f9fe5d0/build_asan/bin/exiv2+0x421e18)

0x60200000ef31 is located 0 bytes to the right of 1-byte region [0x60200000ef30,0x60200000ef31)
allocated by thread T0 here:
    #0 0x7feaa914a6b2 in operator new[](unsigned long) (/usr/lib/x86_64-linux-gnu/libasan.so.2+0x996b2)
    #1 0x453bb9 in Exiv2::DataBuf::DataBuf(long) /home/marsman/Desktop/crashana/exiv2/exiv2-ce516eddefbebd31749b361a540832f41f9fe5d0/include/exiv2/types.hpp:214
    #2 0x7feaa8a4db3a in Exiv2::PngImage::readMetadata() /home/marsman/Desktop/crashana/exiv2/exiv2-ce516eddefbebd31749b361a540832f41f9fe5d0/src/pngimage.cpp:450
    #3 0x43a4b7 in Action::Print::printSummary() /home/marsman/Desktop/crashana/exiv2/exiv2-ce516eddefbebd31749b361a540832f41f9fe5d0/src/actions.cpp:291
    #4 0x439d2f in Action::Print::run(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&) /home/marsman/Desktop/crashana/exiv2/exiv2-ce516eddefbebd31749b361a540832f41f9fe5d0/src/actions.cpp:251
    #5 0x422407 in main /home/marsman/Desktop/crashana/exiv2/exiv2-ce516eddefbebd31749b361a540832f41f9fe5d0/src/exiv2.cpp:166
    #6 0x7feaa7cea82f in __libc_start_main (/lib/x86_64-linux-gnu/libc.so.6+0x2082f)

SUMMARY: AddressSanitizer: heap-buffer-overflow /home/marsman/Desktop/crashana/exiv2/exiv2-ce516eddefbebd31749b361a540832f41f9fe5d0/src/pngchunk_int.cpp:140 Exiv2::Internal::PngChunk::parseTXTChunk(Exiv2::DataBuf const&, int, Exiv2::Internal::PngChunk::TxtChunkType)
Shadow bytes around the buggy address:
  0x0c047fff9d90: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x0c047fff9da0: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x0c047fff9db0: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x0c047fff9dc0: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x0c047fff9dd0: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
=>0x0c047fff9de0: fa fa fa fa fa fa[01]fa fa fa fd fd fa fa 00 fa
  0x0c047fff9df0: fa fa 00 fa fa fa 00 fa fa fa 00 fa fa fa fd fd
  0x0c047fff9e00: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x0c047fff9e10: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x0c047fff9e20: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x0c047fff9e30: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
Shadow byte legend (one shadow byte represents 8 application bytes):
  Addressable:           00
  Partially addressable: 01 02 03 04 05 06 07 
  Heap left redzone:       fa
  Heap right redzone:      fb
  Freed heap region:       fd
  Stack left redzone:      f1
  Stack mid redzone:       f2
  Stack right redzone:     f3
  Stack partial redzone:   f4
  Stack after return:      f5
  Stack use after scope:   f8
  Global redzone:          f9
  Global init order:       f6
  Poisoned by user:        f7
  Container overflow:      fc
  Array cookie:            ac
  Intra object redzone:    bb
  ASan internal:           fe
==27206==ABORTING
```

###  POC2

https://github.com/Marsman1996/pocs/blob/master/exiv2/CVE-2018-16336/poc2-heapoverflow
```
./bin/exiv2 ../../poc2-heapoverflow 
=================================================================
==27229==ERROR: AddressSanitizer: heap-buffer-overflow on address 0x60200000ef5e at pc 0x7f109485cf94 bp 0x7ffded4341f0 sp 0x7ffded4341e0
READ of size 1 at 0x60200000ef5e thread T0
    #0 0x7f109485cf93 in bool __gnu_cxx::__ops::_Iter_equals_val<char const>::operator()<unsigned char*>(unsigned char*) /usr/include/c++/5/bits/predefined_ops.h:194
    #1 0x7f109485cebd in std::iterator_traits<unsigned char*>::difference_type std::__count_if<unsigned char*, __gnu_cxx::__ops::_Iter_equals_val<char const> >(unsigned char*, unsigned char*, __gnu_cxx::__ops::_Iter_equals_val<char const>) /usr/include/c++/5/bits/stl_algo.h:3193
    #2 0x7f109485cd63 in std::iterator_traits<unsigned char*>::difference_type std::count<unsigned char*, char>(unsigned char*, unsigned char*, char const&) /usr/include/c++/5/bits/stl_algo.h:3968
    #3 0x7f10948583ef in Exiv2::Internal::PngChunk::parseTXTChunk(Exiv2::DataBuf const&, int, Exiv2::Internal::PngChunk::TxtChunkType) /home/marsman/Desktop/crashana/exiv2/exiv2-ce516eddefbebd31749b361a540832f41f9fe5d0/src/pngchunk_int.cpp:167
    #4 0x7f10948579e7 in Exiv2::Internal::PngChunk::decodeTXTChunk(Exiv2::Image*, Exiv2::DataBuf const&, Exiv2::Internal::PngChunk::TxtChunkType) /home/marsman/Desktop/crashana/exiv2/exiv2-ce516eddefbebd31749b361a540832f41f9fe5d0/src/pngchunk_int.cpp:83
    #5 0x7f1094797e07 in Exiv2::PngImage::readMetadata() /home/marsman/Desktop/crashana/exiv2/exiv2-ce516eddefbebd31749b361a540832f41f9fe5d0/src/pngimage.cpp:495
    #6 0x43a4b7 in Action::Print::printSummary() /home/marsman/Desktop/crashana/exiv2/exiv2-ce516eddefbebd31749b361a540832f41f9fe5d0/src/actions.cpp:291
    #7 0x439d2f in Action::Print::run(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&) /home/marsman/Desktop/crashana/exiv2/exiv2-ce516eddefbebd31749b361a540832f41f9fe5d0/src/actions.cpp:251
    #8 0x422407 in main /home/marsman/Desktop/crashana/exiv2/exiv2-ce516eddefbebd31749b361a540832f41f9fe5d0/src/exiv2.cpp:166
    #9 0x7f1093a3482f in __libc_start_main (/lib/x86_64-linux-gnu/libc.so.6+0x2082f)
    #10 0x421e18 in _start (/home/marsman/Desktop/crashana/exiv2/exiv2-ce516eddefbebd31749b361a540832f41f9fe5d0/build_asan/bin/exiv2+0x421e18)

0x60200000ef5e is located 1 bytes to the right of 13-byte region [0x60200000ef50,0x60200000ef5d)
allocated by thread T0 here:
    #0 0x7f1094e946b2 in operator new[](unsigned long) (/usr/lib/x86_64-linux-gnu/libasan.so.2+0x996b2)
    #1 0x453bb9 in Exiv2::DataBuf::DataBuf(long) /home/marsman/Desktop/crashana/exiv2/exiv2-ce516eddefbebd31749b361a540832f41f9fe5d0/include/exiv2/types.hpp:214
    #2 0x7f1094797b3a in Exiv2::PngImage::readMetadata() /home/marsman/Desktop/crashana/exiv2/exiv2-ce516eddefbebd31749b361a540832f41f9fe5d0/src/pngimage.cpp:450
    #3 0x43a4b7 in Action::Print::printSummary() /home/marsman/Desktop/crashana/exiv2/exiv2-ce516eddefbebd31749b361a540832f41f9fe5d0/src/actions.cpp:291
    #4 0x439d2f in Action::Print::run(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&) /home/marsman/Desktop/crashana/exiv2/exiv2-ce516eddefbebd31749b361a540832f41f9fe5d0/src/actions.cpp:251
    #5 0x422407 in main /home/marsman/Desktop/crashana/exiv2/exiv2-ce516eddefbebd31749b361a540832f41f9fe5d0/src/exiv2.cpp:166
    #6 0x7f1093a3482f in __libc_start_main (/lib/x86_64-linux-gnu/libc.so.6+0x2082f)

SUMMARY: AddressSanitizer: heap-buffer-overflow /usr/include/c++/5/bits/predefined_ops.h:194 bool __gnu_cxx::__ops::_Iter_equals_val<char const>::operator()<unsigned char*>(unsigned char*)
Shadow bytes around the buggy address:
  0x0c047fff9d90: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x0c047fff9da0: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x0c047fff9db0: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x0c047fff9dc0: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x0c047fff9dd0: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
=>0x0c047fff9de0: fa fa fa fa fa fa 00 03 fa fa 00[05]fa fa 00 fa
  0x0c047fff9df0: fa fa 00 fa fa fa 00 fa fa fa 00 fa fa fa fd fd
  0x0c047fff9e00: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x0c047fff9e10: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x0c047fff9e20: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x0c047fff9e30: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
Shadow byte legend (one shadow byte represents 8 application bytes):
  Addressable:           00
  Partially addressable: 01 02 03 04 05 06 07 
  Heap left redzone:       fa
  Heap right redzone:      fb
  Freed heap region:       fd
  Stack left redzone:      f1
  Stack mid redzone:       f2
  Stack right redzone:     f3
  Stack partial redzone:   f4
  Stack after return:      f5
  Stack use after scope:   f8
  Global redzone:          f9
  Global init order:       f6
  Poisoned by user:        f7
  Container overflow:      fc
  Array cookie:            ac
  Intra object redzone:    bb
  ASan internal:           fe
==27229==ABORTING
```


Comments:
Comment by D4N on 2018-08-14 05:19:55+00:00:
Thanks for your reports! I'll fix these today after work.

Just out of curiosity, have you published mem-AFL? And how does it compare to vanilla-AFL?

---

Comment by Marsman1996 on 2018-08-14 06:21:05+00:00:
Hi, 

we haven't published mem-AFL yet, but we will publish its source code after our paper being published.

And the details of comparison will be discussed in out paper.

---

Comment by D4N on 2018-08-14 08:44:07+00:00:
Cool, could you guys drop me an email once everything is published? (You can find my email in the commit log.)

Do you plan to fuzz exiv2 further? If yes, I could give you some hints what to test further.

---

Comment by Marsman1996 on 2018-08-14 11:08:11+00:00:
Yes, we will send you an email once everything is done.

We plan to fuzz exiv2 further and we look forward to receiving your hints. We could communicate by email.

Commit References:
ce516eddefbebd31749b361a540832f41f9fe5d0

Build script:
#!/bin/bash -eu
# Minimized build script with only core build commands
set -eu
mkdir -p build
cd build
cmake -DEXIV2_ENABLE_PNG=ON -DEXIV2_ENABLE_WEBREADY=ON -DEXIV2_ENABLE_CURL=OFF -DEXIV2_ENABLE_BMFF=ON -DEXIV2_TEAM_WARNINGS_AS_ERRORS=ON -DBUILD_SHARED_LIBS=OFF -DCMAKE_CXX_COMPILER="${CXX}" -DCMAKE_CXX_FLAGS="${CXXFLAGS}" -DEXIV2_BUILD_FUZZ_TESTS=ON -DEXIV2_TEAM_OSS_FUZZ=ON -DLIB_FUZZING_ENGINE="${LIB_FUZZING_ENGINE}" ..
make -j $(nproc)

Dockerfile:
FROM hwiwonlee/secb.base:latest
RUN apt-get update && apt-get install -y cmake make ccache python3 libexpat1-dev zlib1g-dev libssh-dev libcurl4-openssl-dev libxml2-utils
RUN git clone https://github.com/exiv2/exiv2 exiv2
RUN git -C exiv2 checkout fa449a4d2c58d63f0d75ff259f25683a98a44630
WORKDIR $SRC/exiv2
COPY build.sh $SRC/

Additional files: