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

================= Bug Report (1/1) ==================
## Source: GitHub Issue
## URL: https://github.com/Exiv2/exiv2/issues/428
## Description:
Issue: Exiv2/exiv2#428
Title: CVE-2018-19535: AddressSanitizer: heap-buffer-overflow at pngchunk_int.cpp:635
State: closed
Created by: hongxuchen
Created at: 2018-09-01 05:40:24+00:00
Labels: bug

Issue Body:
When running `exiv2 $FILE` (5940c6f) against png files, , ASAN reports a heap-buffer-overflow error.

POCs:
https://github.com/ntu-sec/pocs/blob/master/exiv2-5940c6f3/crashes/hbo_pngchunk_int.cpp:635_1.png
https://github.com/ntu-sec/pocs/blob/master/exiv2-5940c6f3/crashes/hbo_pngchunk_int.cpp:635_2.png

ASAN output:
```
=================================================================
==32119==ERROR: AddressSanitizer: heap-buffer-overflow on address 0x6070000001bf at pc 0x7fea19eca9aa bp 0x7ffd00c71d70 sp 0x7ffd00c71d68
READ of size 1 at 0x6070000001bf thread T0
    #0 0x7fea19eca9a9 in Exiv2::Internal::PngChunk::readRawProfile(Exiv2::DataBuf const&, bool) /home/hongxu/FOT/exiv2/src/pngchunk_int.cpp:635:16
    #1 0x7fea19ec7228 in Exiv2::Internal::PngChunk::parseChunkContent(Exiv2::Image*, unsigned char const*, long, Exiv2::DataBuf) /home/hongxu/FOT/exiv2/src/pngchunk_int.cpp:258:32
    #2 0x7fea19ec4f6f in Exiv2::Internal::PngChunk::decodeTXTChunk(Exiv2::Image*, Exiv2::DataBuf const&, Exiv2::Internal::PngChunk::TxtChunkType) /home/hongxu/FOT/exiv2/src/pngchunk_int.cpp:91:9
    #3 0x7fea19d74647 in Exiv2::PngImage::readMetadata() /home/hongxu/FOT/exiv2/src/pngimage.cpp:495:21
    #4 0x55b70c in Action::Print::printSummary() /home/hongxu/FOT/exiv2/src/actions.cpp:288:16
    #5 0x55a19a in Action::Print::run(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&) /home/hongxu/FOT/exiv2/src/actions.cpp:248:48
    #6 0x532dcb in main /home/hongxu/FOT/exiv2/src/exiv2.cpp:166:29
    #7 0x7fea18220b96 in __libc_start_main /build/glibc-OTsEL5/glibc-2.27/csu/../csu/libc-start.c:310
    #8 0x435ac9 in _start (/home/hongxu/FOT/exiv2/install/bin/exiv2+0x435ac9)

0x6070000001bf is located 0 bytes to the right of 79-byte region [0x607000000170,0x6070000001bf)
allocated by thread T0 here:
    #0 0x52e0f0 in operator new[](unsigned long) (/home/hongxu/FOT/exiv2/install/bin/exiv2+0x52e0f0)
    #1 0x7fea19ce7af9 in Exiv2::DataBuf::DataBuf(unsigned char const*, long) /home/hongxu/FOT/exiv2/src/types.cpp:138:22
    #2 0x7fea19ec6831 in Exiv2::Internal::PngChunk::parseTXTChunk(Exiv2::DataBuf const&, int, Exiv2::Internal::PngChunk::TxtChunkType) /home/hongxu/FOT/exiv2/src/pngchunk_int.cpp:216:27
    #3 0x7fea19ec4dcc in Exiv2::Internal::PngChunk::decodeTXTChunk(Exiv2::Image*, Exiv2::DataBuf const&, Exiv2::Internal::PngChunk::TxtChunkType) /home/hongxu/FOT/exiv2/src/pngchunk_int.cpp:85:23
    #4 0x7fea19d74647 in Exiv2::PngImage::readMetadata() /home/hongxu/FOT/exiv2/src/pngimage.cpp:495:21
    #5 0x55b70c in Action::Print::printSummary() /home/hongxu/FOT/exiv2/src/actions.cpp:288:16
    #6 0x55a19a in Action::Print::run(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&) /home/hongxu/FOT/exiv2/src/actions.cpp:248:48
    #7 0x532dcb in main /home/hongxu/FOT/exiv2/src/exiv2.cpp:166:29
    #8 0x7fea18220b96 in __libc_start_main /build/glibc-OTsEL5/glibc-2.27/csu/../csu/libc-start.c:310

SUMMARY: AddressSanitizer: heap-buffer-overflow /home/hongxu/FOT/exiv2/src/pngchunk_int.cpp:635:16 in Exiv2::Internal::PngChunk::readRawProfile(Exiv2::DataBuf const&, bool)
Shadow bytes around the buggy address:
  0x0c0e7fff7fe0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x0c0e7fff7ff0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x0c0e7fff8000: fa fa fa fa fd fd fd fd fd fd fd fd fd fd fa fa
  0x0c0e7fff8010: fa fa 00 00 00 00 00 00 00 00 00 03 fa fa fa fa
  0x0c0e7fff8020: fd fd fd fd fd fd fd fd fd fd fa fa fa fa 00 00
=>0x0c0e7fff8030: 00 00 00 00 00 00 00[07]fa fa fa fa fa fa fa fa
  0x0c0e7fff8040: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x0c0e7fff8050: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x0c0e7fff8060: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x0c0e7fff8070: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x0c0e7fff8080: 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
  Freed heap region:       fd
  Stack left redzone:      f1
  Stack mid redzone:       f2
  Stack right redzone:     f3
  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
  Left alloca redzone:     ca
  Right alloca redzone:    cb
==32119==ABORTING
```


Comments:
Comment by hongxuchen on 2018-09-02 03:24:58+00:00:
A relevant heap-buffer-overflow at pngchunk_int.cpp:645:
https://github.com/ntu-sec/pocs/blob/master/exiv2-5940c6f3/crashes/hbo_pngchunk_int.cpp:645_1.png
https://github.com/ntu-sec/pocs/blob/master/exiv2-5940c6f3/crashes/hbo_pngchunk_int.cpp:645_2.png

---

Comment by piponazo on 2018-09-02 06:27:25+00:00:
Thanks @HongxuChen for reporting. I confirm that I could reproduce the issue and I will take a look to this issue

---

Comment by hongxuchen on 2018-09-02 14:59:44+00:00:
@piponazo This fixes Line 635 issue. The line 645 issue still exists.
https://github.com/ntu-sec/pocs/blob/master/exiv2-5940c6f3/crashes/hbo_pngchunk_int.cpp:645_1.png
https://github.com/ntu-sec/pocs/blob/master/exiv2-5940c6f3/crashes/hbo_pngchunk_int.cpp:645_2.png

Also, our fuzzer found a few other relevant cases in 5940c6f but exists after the PR.
https://github.com/ntu-sec/pocs/blob/master/exiv2-5940c6f3/crashes/hbo_pngchunk_int.cpp:643_1.png
https://github.com/ntu-sec/pocs/blob/master/exiv2-5940c6f3/crashes/hbo_pngchunk_int.cpp:643_2.png
https://github.com/ntu-sec/pocs/blob/master/exiv2-5940c6f3/crashes/hbo_pngchunk_int.cpp:674_1.png
https://github.com/ntu-sec/pocs/blob/master/exiv2-5940c6f3/crashes/hbo_pngchunk_int.cpp:674_2.png




---

Comment by piponazo on 2018-09-02 15:46:20+00:00:
I will double check again. I do not know much about that piece of code and it is also difficult to find some specification to determine how a "good implementation" should look like. 

---

Comment by piponazo on 2018-09-03 06:56:08+00:00:
@HongxuChen I could fix the issues detected with the 2 other POCs reported initially (line 645).

However I do not understand yet enough about the PNG specification to fix the rest of issues detected. I have the feeling that for fixing all the issues in this function we will need much more time to understand the PNG specification, and also to rewrite such method. I do not think I can address all these changes for the v0.27 RC1. Therefore I propose to merge the fixes done in #430, which will solve have of the issues, and leave this issue open as a remanding for the rest of issues you detected.

---

Comment by hongxuchen on 2018-09-03 07:17:03+00:00:
@piponazo  :ok_hand: 

---

Comment by clanmills on 2018-09-03 09:59:08+00:00:
Thanks for looking into this @piponazo 

I've assigned myself to this, although I agree with you that we are unlikely to resolved this for v0.27 RC1.

---

Comment by clanmills on 2018-09-04 12:19:49+00:00:
I have a working knowledge of the PNG Specification.  Tuan added this page about it to our Wiki in 2013:  http://dev.exiv2.org/projects/exiv2/wiki/The_Metadata_in_PNG_files

I have reproduced this and will work on this later today (it's currently Tuesday 2018-09-04 13:19BST)

Here's what I can see:
I've build with ASAN:
```
1102 rmills@rmillsmm:~/gnu/github/exiv2/exiv2/build $ cmake .. -G "Unix Makefiles" -DEXIV2_TEAM_USE_SANITIZERS=On
```
Here are the POC files:
```
1251 rmills@rmillsmm:~/Downloads $ ls -alts *.png
4 -rw-r--r--+ 1 rmills staff  176 Sep  5 19:34 hbo_pngchunk_int.cpp-635_2.png
4 -rw-r--r--+ 1 rmills staff 1497 Sep  5 19:34 hbo_pngchunk_int.cpp-635_1.png
4 -rw-r--r--+ 1 rmills staff  188 Sep  4 13:09 hbo_pngchunk_int.cpp-674_2.png
4 -rw-r--r--+ 1 rmills staff 2598 Sep  4 13:09 hbo_pngchunk_int.cpp-674_1.png
4 -rw-r--r--+ 1 rmills staff  456 Sep  4 13:08 hbo_pngchunk_int.cpp-643_2.png
4 -rw-r--r--+ 1 rmills staff 1651 Sep  4 13:07 hbo_pngchunk_int.cpp-643_1.png
4 -rw-r--r--+ 1 rmills staff  188 Sep  4 13:05 hbo_pngchunk_int.cpp-645_2.png
4 -rw-r--r--+ 1 rmills staff  512 Sep  4 13:05 hbo_pngchunk_int.cpp-645_1.png
1252 rmills@rmillsmm:~/Downloads $ 
```

When I execute exiv2, I get:
```
1128 rmills@rmillsmm:~/gnu/github/exiv2/exiv2/build $ for i in $(ls ~/Downloads/*.png|sort); do echo ---- $i ---- ; bin/exiv2 --verbose $i 2>&1 | grep SUMMARY ; echo '' ; done
---- /Users/rmills/Downloads/hbo_pngchunk_int.cpp-635_1.png ----
SUMMARY: AddressSanitizer: heap-buffer-overflow (libexiv2.26.dylib:x86_64+0x1254b39) in Exiv2::Internal::PngChunk::readRawProfile(Exiv2::DataBuf const&, bool)

---- /Users/rmills/Downloads/hbo_pngchunk_int.cpp-635_2.png ----
SUMMARY: AddressSanitizer: heap-buffer-overflow (libexiv2.26.dylib:x86_64+0x1254b39) in Exiv2::Internal::PngChunk::readRawProfile(Exiv2::DataBuf const&, bool)

---- /Users/rmills/Downloads/hbo_pngchunk_int.cpp-643_1.png ----
SUMMARY: AddressSanitizer: heap-buffer-overflow (libclang_rt.asan_osx_dynamic.dylib:x86_64+0x52534) in wrap_atol

---- /Users/rmills/Downloads/hbo_pngchunk_int.cpp-643_2.png ----
SUMMARY: AddressSanitizer: heap-buffer-overflow (libclang_rt.asan_osx_dynamic.dylib:x86_64+0x52534) in wrap_atol

---- /Users/rmills/Downloads/hbo_pngchunk_int.cpp-645_1.png ----
SUMMARY: AddressSanitizer: heap-buffer-overflow (libexiv2.26.dylib:x86_64+0x1254eb2) in Exiv2::Internal::PngChunk::readRawProfile(Exiv2::DataBuf const&, bool)

---- /Users/rmills/Downloads/hbo_pngchunk_int.cpp-645_2.png ----
SUMMARY: AddressSanitizer: heap-buffer-overflow (libexiv2.26.dylib:x86_64+0x1254eb2) in Exiv2::Internal::PngChunk::readRawProfile(Exiv2::DataBuf const&, bool)

---- /Users/rmills/Downloads/hbo_pngchunk_int.cpp-674_1.png ----
SUMMARY: AddressSanitizer: heap-buffer-overflow (libexiv2.26.dylib:x86_64+0x12553c2) in Exiv2::Internal::PngChunk::readRawProfile(Exiv2::DataBuf const&, bool)

---- /Users/rmills/Downloads/hbo_pngchunk_int.cpp-674_2.png ----
SUMMARY: AddressSanitizer: heap-buffer-overflow (libexiv2.26.dylib:x86_64+0x12553c2) in Exiv2::Internal::PngChunk::readRawProfile(Exiv2::DataBuf const&, bool)

1129 rmills@rmillsmm:~/gnu/github/exiv2/exiv2/build $ 
```

---

Comment by piponazo on 2018-09-11 08:39:51+00:00:
@clanmills managed to solve the problems triggered by all the POCs, and I adapted the tests in #430 to have regression tests for all these cases. Thanks @HongxuChen for reporting this. 

---

Comment by carnil on 2018-11-30 20:25:40+00:00:
This issue was assigned [CVE-2018-19535](https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2018-19535)

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: