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

================= Bug Report (1/1) ==================
## Source: Red Hat Bugzilla
## URL: https://bugzilla.redhat.com/show_bug.cgi?id=1575201
## Description:
Bugzilla ID: 1575201
Title: Heap Buffer Overflow in image.cpp:260 Exiv2::Image::byteSwap2

Description
albertzjf 2018-05-05 04:55:06 UTC
Description of problem:
Heap Buffer Overflow in image.cpp:260 Exiv2::Image::byteSwap2

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

How reproducible:
./exiv2 POC /dev/null

Steps to Reproduce:
1.
2.
3.

=================================================================
==98057==ERROR: AddressSanitizer: heap-buffer-overflow on address 0x60200000ed54 at pc 0x7f550604e903 bp 0x7fff2502ebd0 sp 0x7fff2502ebc0
READ of size 1 at 0x60200000ed54 thread T0
    #0 0x7f550604e902 in Exiv2::Image::byteSwap2(Exiv2::DataBuf&, unsigned long, bool) /home/puppet/test_object_pic/exiv2-trunk/src/image.cpp:260
    #1 0x7f5506050573 in Exiv2::Image::printIFDStructure(Exiv2::BasicIo&, std::ostream&, Exiv2::PrintStructureOption, unsigned int, bool, char, int) /home/puppet/test_object_pic/exiv2-trunk/src/image.cpp:418
    #2 0x7f55060518a3 in Exiv2::Image::printTiffStructure(Exiv2::BasicIo&, std::ostream&, Exiv2::PrintStructureOption, int, unsigned long) /home/puppet/test_object_pic/exiv2-trunk/src/image.cpp:517
    #3 0x7f55060bbb27 in Exiv2::OrfImage::printStructure(std::ostream&, Exiv2::PrintStructureOption, int) /home/puppet/test_object_pic/exiv2-trunk/src/orfimage.cpp:104
    #4 0x7f55060bc0da in Exiv2::OrfImage::readMetadata() /home/puppet/test_object_pic/exiv2-trunk/src/orfimage.cpp:123
    #5 0x43ab12 in Action::Print::printSummary() /home/puppet/test_object_pic/exiv2-trunk/src/actions.cpp:289
    #6 0x43a1bf in Action::Print::run(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&) /home/puppet/test_object_pic/exiv2-trunk/src/actions.cpp:244
    #7 0x422139 in main /home/puppet/test_object_pic/exiv2-trunk/src/exiv2.cpp:170
    #8 0x7f55053af82f in __libc_start_main (/lib/x86_64-linux-gnu/libc.so.6+0x2082f)
    #9 0x421b08 in _start (/usr/local/bin/exiv2+0x421b08)

0x60200000ed54 is located 0 bytes to the right of 4-byte region [0x60200000ed50,0x60200000ed54)
allocated by thread T0 here:
    #0 0x7f55067dd6b2 in operator new[](unsigned long) (/usr/lib/x86_64-linux-gnu/libasan.so.2+0x996b2)
    #1 0x454815 in Exiv2::DataBuf::DataBuf(long) /home/puppet/test_object_pic/exiv2-trunk/include/exiv2/types.hpp:204
    #2 0x7f550605014d in Exiv2::Image::printIFDStructure(Exiv2::BasicIo&, std::ostream&, Exiv2::PrintStructureOption, unsigned int, bool, char, int) /home/puppet/test_object_pic/exiv2-trunk/src/image.cpp:402
    #3 0x7f55060518a3 in Exiv2::Image::printTiffStructure(Exiv2::BasicIo&, std::ostream&, Exiv2::PrintStructureOption, int, unsigned long) /home/puppet/test_object_pic/exiv2-trunk/src/image.cpp:517
    #4 0x7f55060bbb27 in Exiv2::OrfImage::printStructure(std::ostream&, Exiv2::PrintStructureOption, int) /home/puppet/test_object_pic/exiv2-trunk/src/orfimage.cpp:104
    #5 0x7f55060bc0da in Exiv2::OrfImage::readMetadata() /home/puppet/test_object_pic/exiv2-trunk/src/orfimage.cpp:123
    #6 0x43ab12 in Action::Print::printSummary() /home/puppet/test_object_pic/exiv2-trunk/src/actions.cpp:289
    #7 0x43a1bf in Action::Print::run(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&) /home/puppet/test_object_pic/exiv2-trunk/src/actions.cpp:244
    #8 0x422139 in main /home/puppet/test_object_pic/exiv2-trunk/src/exiv2.cpp:170
    #9 0x7f55053af82f in __libc_start_main (/lib/x86_64-linux-gnu/libc.so.6+0x2082f)

SUMMARY: AddressSanitizer: heap-buffer-overflow /home/puppet/test_object_pic/exiv2-trunk/src/image.cpp:260 Exiv2::Image::byteSwap2(Exiv2::DataBuf&, unsigned long, bool)
Shadow bytes around the buggy address:
  0x0c047fff9d50: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x0c047fff9d60: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x0c047fff9d70: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x0c047fff9d80: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  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[04]fa fa fa 00 fa
  0x0c047fff9db0: fa fa 00 fa fa fa 00 fa fa fa fd fd fa fa fd fa
  0x0c047fff9dc0: fa fa 06 fa fa fa 00 04 fa fa 00 04 fa fa 00 04
  0x0c047fff9dd0: fa fa 00 04 fa fa 00 04 fa fa 00 04 fa fa 00 04
  0x0c047fff9de0: fa fa 00 04 fa fa 00 04 fa fa 00 04 fa fa 00 04
  0x0c047fff9df0: fa fa 00 04 fa fa 00 04 fa fa 00 04 fa fa fd 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
==98057==ABORTING


This vulnerability was triggered in Exiv2::Image::byteSwap2(Exiv2::DataBuf&, unsigned long, bool) at src/image.cpp:260

    uint16_t Image::byteSwap2(DataBuf& buf,size_t offset,bool bSwap)
    {
        uint16_t v;
        char*    p = (char*) &v;
        p[0] = buf.pData_[offset];
        p[1] = buf.pData_[offset+1];
        return Image::byteSwap(v,bSwap);
    }


Actual results:
crash

Expected results:
crash

Additional info:
This vulnerability is detected by NESA Lab(nesa.zju.edu.cn), with our custom
seed generate system, SmartSeed. Please contact  puppet.cn  and
albertzjf if you need more info about the team, the tool or the
vulnerability.


Comments:
Comment 2
albertzjf 2018-05-09 08:18:48 UTC
Created attachment 1433611 [details]
poc file

---

Comment 3
Pedro Yóssis Silva Barbosa 2018-05-25 21:18:46 UTC
Could you please provide more information regarding your findings?

The provided POC didn't crash here in RHEL 7. Moreover, the Exiv2::Image::byteSwap2 in /usr/lib64/libexiv2.so wasn't even called at all.




[pedroysb@rhel-7 sf_rhel_shared]$ gdb /usr/bin/exiv2
pwndbg> # breakpoint at main
pwndbg> b *0x406850
pwndbg> run POC
...
Breakpoint *0x406850
pwndbg> b _ZN5Exiv25Image9byteSwap2ERNS_7DataBufEmb
Breakpoint 2 at 0x7ffff75ce160
pwndbg> c
Continuing.
Error: Directory Image: IFD entry 23 lies outside of the data buffer.
Error: Directory Image, entry 0x0000 has invalid size 4294967288*2; skipping entry.
Warning: Directory Image, entry 0x0000 has unknown Exif (TIFF) type 65280; setting type size 1.
Warning: Directory Image, entry 0x0000 has unknown Exif (TIFF) type 0; setting type size 1.
Error: Offset of directory Image, entry 0x0000 is out of bounds: Offset = 0x00000000; truncating the entry
Error: Directory Image, entry 0x0000 has invalid size 4278135811*1; skipping entry.
Warning: Directory Image, entry 0x0000 has unknown Exif (TIFF) type 0; setting type size 1.
Warning: Directory Image, entry 0x0000 has unknown Exif (TIFF) type 0; setting type size 1.
Warning: Directory Image, entry 0x0000 has unknown Exif (TIFF) type 61440; setting type size 1.
Error: Directory Image, entry 0x0000 has invalid size 4278135811*1; skipping entry.
Warning: Directory Image, entry 0x000e has unknown Exif (TIFF) type 11267; setting type size 1.
Error: Upper boundary of data for directory Image, entry 0x000e is out of bounds: Offset = 0x00000010, size = 65279, exceeds buffer size by 64999 Bytes; truncating the entry
Warning: Directory Image, entry 0x0000 has unknown Exif (TIFF) type 65280; setting type size 1.
Warning: Directory Image, entry 0x0000 has unknown Exif (TIFF) type 0; setting type size 1.
Error: Offset of directory Image, entry 0x0000 is out of bounds: Offset = 0x00000000; truncating the entry
Error: Directory Image, entry 0x0000 has invalid size 4278135811*1; skipping entry.
Warning: Directory Image, entry 0x0000 has unknown Exif (TIFF) type 0; setting type size 1.
Warning: Directory Image, entry 0x0000 has unknown Exif (TIFF) type 0; setting type size 1.
Warning: Directory Image, entry 0x0000 has unknown Exif (TIFF) type 65280; setting type size 1.
Error: Offset of directory Image, entry 0x0000 is out of bounds: Offset = 0x00000000; truncating the entry
Warning: Directory Image, entry 0x0000 has unknown Exif (TIFF) type 65278; setting type size 1.
Warning: Directory Image, entry 0x002c has unknown Exif (TIFF) type 0; setting type size 1.
Error: Directory Image, entry 0x002c has invalid size 4278190080*1; skipping entry.
Warning: Directory Image, entry 0x0000 has unknown Exif (TIFF) type 0; setting type size 1.
Error: Directory Image, entry 0x0000 has invalid size 4278059008*1; skipping entry.
File name       : POC
File size       : 296 Bytes
MIME type       : image/x-olympus-orf
Image size      : 0 x 0
Camera make     : 
Camera model    : 
Image timestamp : 
Image number    : 
Exposure time   : 
Aperture        : 
Exposure bias   : 
Flash           : 
Flash bias      : 
Focal length    : 
Subject distance: 
ISO speed       : 
Exposure mode   : 
Metering mode   : 
Macro mode      : 
Image quality   : 
Exif Resolution : 
White balance   : 
Thumbnail       : None
Copyright       : 
Exif comment    : 

[Inferior 1 (process 26135) exited normally]
pwndbg> 


When I intercept the library function calls using ltrace, the byteSwap2 function doesn't appear in the logs too (see attachment).

---

Comment 4
Pedro Yóssis Silva Barbosa 2018-05-25 21:21:56 UTC
Created attachment 1441710 [details]
ltrace output

---

Comment 5
albertzjf 2018-05-26 01:21:49 UTC
Sorry for misleading. The crash was actually triggered in Ubuntu 16.04 by this POC when we tested. When to report, I found most CVEs of exiv2 was referenced to this website, and I thought there wouldn't be much difference.

---

Comment 6
Pedro Yóssis Silva Barbosa 2018-05-29 17:51:11 UTC
Closing as NOTABUG

Attachments:
Attachment 1433611: poc file [Link: https://bugzilla.redhat.com/attachment.cgi?id=1433611]
Attachment 1441710: ltrace output [Link: https://bugzilla.redhat.com/attachment.cgi?id=1441710]

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: