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

================= Bug Report (1/2) ==================
## Source: Red Hat Bugzilla
## URL: https://bugzilla.redhat.com/show_bug.cgi?id=1524107
## Description:
Bugzilla ID: 1524107
Title: exiv2 library: heap-based buffer over-read in Exiv2::IptcData::printStructure (iptc.cpp)

Description
Wei You 2017-12-10 06:21:33 UTC
Created attachment 1365483 [details]
poc to trigger the vulnerability

on 0.26 (the latest version):

there is a heap-based buffer over-read in the Exiv2::IptcData::printStructure function (src/iptc.cpp), which can be triggered by poc_1.tiff in the
attachment.

Note that this vulnerability exists in the exiv2 library, any software using
exiv2 will be affected by this vulnerability. Remote attackers can exploit
this vulnerability to cause a denial of service via a crafted tiff file.

As a demonstration, please run the following command-line to trigger this
vulnerability:


./0.26/bin/exiv2 poc_1.tiff 
=================================================================
==12019==ERROR: AddressSanitizer: heap-buffer-overflow on address 0x60200000ed71 at pc 0x00000063908e bp 0x7ffe694d4400 sp 0x7ffe694d43f0
READ of size 1 at 0x60200000ed71 thread T0
    #0 0x63908d in Exiv2::IptcData::printStructure(std::ostream&, unsigned char const*, unsigned long, unsigned int) /home/fuzz/exiv2/0.26/src/iptc.cpp:359
    #1 0x61d9d2 in Exiv2::Image::printIFDStructure(Exiv2::BasicIo&, std::ostream&, Exiv2::PrintStructureOption, unsigned int, bool, char, int) /home/fuzz/exiv2/0.26/src/image.cpp:454
    #2 0x622035 in Exiv2::Image::printTiffStructure(Exiv2::BasicIo&, std::ostream&, Exiv2::PrintStructureOption, int, unsigned long) /home/fuzz/exiv2/0.26/src/image.cpp:517
    #3 0x7ea794 in Exiv2::TiffImage::printStructure(std::ostream&, Exiv2::PrintStructureOption, int) /home/fuzz/exiv2/0.26/src/tiffimage.cpp:348
    #4 0x7fa25d in Exiv2::TiffImage::readMetadata() /home/fuzz/exiv2/0.26/src/tiffimage.cpp:191
    #5 0x4f2ea6 in Action::Print::printSummary() /home/fuzz/exiv2/0.26/src/actions.cpp:289
    #6 0x4f7907 in Action::Print::run(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&) /home/fuzz/exiv2/0.26/src/actions.cpp:244
    #7 0x409cec in main /home/fuzz/exiv2/0.26/src/exiv2.cpp:170
    #8 0x7fc10c3c082f in __libc_start_main (/lib/x86_64-linux-gnu/libc.so.6+0x2082f)
    #9 0x48f718 in _start (/home/fuzz/exiv2/0.26/bin/exiv2+0x48f718)

0x60200000ed71 is located 0 bytes to the right of 1-byte region [0x60200000ed70,0x60200000ed71)
allocated by thread T0 here:
    #0 0x7fc10d7046b2 in operator new[](unsigned long) (/usr/lib/x86_64-linux-gnu/libasan.so.2+0x996b2)
    #1 0x61d873 in Exiv2::Image::printIFDStructure(Exiv2::BasicIo&, std::ostream&, Exiv2::PrintStructureOption, unsigned int, bool, char, int) /home/fuzz/exiv2/0.26/src/image.cpp:451
    #2 0x622035 in Exiv2::Image::printTiffStructure(Exiv2::BasicIo&, std::ostream&, Exiv2::PrintStructureOption, int, unsigned long) /home/fuzz/exiv2/0.26/src/image.cpp:517
    #3 0x7ea794 in Exiv2::TiffImage::printStructure(std::ostream&, Exiv2::PrintStructureOption, int) /home/fuzz/exiv2/0.26/src/tiffimage.cpp:348

SUMMARY: AddressSanitizer: heap-buffer-overflow /home/fuzz/exiv2/0.26/src/iptc.cpp:359 Exiv2::IptcData::printStructure(std::ostream&, unsigned char const*, unsigned long, unsigned int)
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 fa fa fa fa[01]fa
  0x0c047fff9db0: fa fa 00 fa fa fa 00 fa fa fa 00 fa fa fa fd fd
  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
==12019==ABORTING


Comments:
Comment 4
Jan Grulich 2019-01-28 16:08:25 UTC
Fixed with exiv2-0.27.0-1.el7_6.

---

Comment 8
errata-xmlrpc 2019-08-06 12:47:14 UTC
Since the problem described in this bug report should be
resolved in a recent advisory, it has been closed with a
resolution of ERRATA.

For information on the advisory, and where to find the updated
files, follow the link below.

If the solution does not work for you, open a new bug report.

https://access.redhat.com/errata/RHSA-2019:2101

Attachments:
Attachment 1365483: poc to trigger the vulnerability [Link: https://bugzilla.redhat.com/attachment.cgi?id=1365483]

================= Bug Report (2/2) ==================
## Source: GitHub Issue
## URL: https://github.com/Exiv2/exiv2/issues/263
## Description:
Issue: Exiv2/exiv2#263
Title:  out bound reads which could  result to segmentfault
State: closed
Created by: xiaoqx
Created at: 2018-04-04 08:16:47+00:00
Labels: bug

Issue Body:
there are other testcases to trigger out of bound read with the commands (exiv2 -pv $POC),
some debug information  as follows:

```
exiv2 -pv $POC

Program received signal SIGSEGV, Segmentation fault.
[----------------------------------registers-----------------------------------]
RAX: 0x66208e
RBX: 0x7ffff78a2ed9 --> 0x63747049002e2e2e ('...')
RCX: 0x0
RDX: 0xf1fe
RSI: 0xffffffff
RDI: 0x0
RBP: 0x7fffffff2ce0 --> 0x7fffffff2ec0 --> 0x7fffffff30a0 --> 0x7fffffff3280 --> 0x7fffffff3460 --> 0x7fffffff3640 (--> ...)
RSP: 0x7fffffff2c20 --> 0x5ff7fe2780
RIP: 0x7ffff778c165 (<Exiv2::IptcData::printStructure(std::ostream&, unsigned char const*, unsigned long, unsigned int)+659>:   movzx  eax,BYTE PTR [rax])
R8 : 0x0
R9 : 0x651fe0 --> 0x0
R10: 0x7ffff7089760 --> 0x0
R11: 0x0
R12: 0x7ffff78a2ac5 --> 0x4853004949435341 ('ASCII')
R13: 0x7fffffffe490 --> 0x3
R14: 0x0
R15: 0x0
EFLAGS: 0x10206 (carry PARITY adjust zero sign trap INTERRUPT direction overflow)                                                                                                                                [-------------------------------------code-------------------------------------]
   0x7ffff778c155 <Exiv2::IptcData::printStructure(std::ostream&, unsigned char const*, unsigned long, unsigned int)+643>:      mov    edx,DWORD PTR [rbp-0x94]
   0x7ffff778c15b <Exiv2::IptcData::printStructure(std::ostream&, unsigned char const*, unsigned long, unsigned int)+649>:      mov    rax,QWORD PTR [rbp-0xb0]
   0x7ffff778c162 <Exiv2::IptcData::printStructure(std::ostream&, unsigned char const*, unsigned long, unsigned int)+656>:      add    rax,rdx
=> 0x7ffff778c165 <Exiv2::IptcData::printStructure(std::ostream&, unsigned char const*, unsigned long, unsigned int)+659>:      movzx  eax,BYTE PTR [rax]
   0x7ffff778c168 <Exiv2::IptcData::printStructure(std::ostream&, unsigned char const*, unsigned long, unsigned int)+662>:      cmp    al,0x1c
   0x7ffff778c16a <Exiv2::IptcData::printStructure(std::ostream&, unsigned char const*, unsigned long, unsigned int)+664>:      jne    0x7ffff778c186 <Exiv2::IptcData::printStructure(std::ostream&, unsigned ch
ar const*, unsigned long, unsigned int)+692>
   0x7ffff778c16c <Exiv2::IptcData::printStructure(std::ostream&, unsigned char const*, unsigned long, unsigned int)+666>:      mov    eax,DWORD PTR [rbp-0x94]
   0x7ffff778c172 <Exiv2::IptcData::printStructure(std::ostream&, unsigned char const*, unsigned long, unsigned int)+672>:      mov    rdx,QWORD PTR [rbp-0xb8]
[------------------------------------stack-------------------------------------]
0000| 0x7fffffff2c20 --> 0x5ff7fe2780
0008| 0x7fffffff2c28 --> 0xf4
0016| 0x7fffffff2c30 --> 0x652e90 --> 0x1300000008002a49
0024| 0x7fffffff2c38 --> 0x7fffffffe050 --> 0x7ffff7592e38 --> 0x7ffff735afb0 (<_ZNSt14basic_ofstreamIcSt11char_traitsIcEED1Ev>:        mov    rax,QWORD PTR [rip+0x238d01]        # 0x7ffff7593cb8)
0032| 0x7fffffff2c40 --> 0x2000000000000
0040| 0x7fffffff2c48 --> 0xf1fef10e0003
0048| 0x7fffffff2c50 --> 0x651ff8 ('.' <repeats 39 times>)
0056| 0x7fffffff2c58 --> 0x644880 --> 0x7ffffbad2488
[------------------------------------------------------------------------------]
Legend: code, data, rodata, value
Stopped reason: SIGSEGV
0x00007ffff778c165 in Exiv2::IptcData::printStructure (out=..., bytes=0x652e90 "I*", size=0xf4, depth=0x5f) at iptc.cpp:357
357                     while ( bytes[i] == 0x1c && i < size-3 ) {
gdb-peda$ bt
#0  0x00007ffff778c165 in Exiv2::IptcData::printStructure (out=..., bytes=0x652e90 "I*", size=0xf4, depth=0x5f) at iptc.cpp:357
#1  0x00007ffff7782379 in Exiv2::Image::printIFDStructure (this=0x644ac0, io=..., out=..., option=Exiv2::kpsRecursive, start=0x8, bSwap=0x0, c=0x49, depth=0x5e) at image.cpp:470
#2  0x00007ffff778218c in Exiv2::Image::printIFDStructure (this=0x644ac0, io=..., out=..., option=Exiv2::kpsRecursive, start=0x8, bSwap=0x0, c=0x49, depth=0x5d) at image.cpp:455
#3  0x00007ffff778218c in Exiv2::Image::printIFDStructure (this=0x644ac0, io=..., out=..., option=Exiv2::kpsRecursive, start=0x8, bSwap=0x0, c=0x49, depth=0x5c) at image.cpp:455
#4  0x00007ffff778218c in Exiv2::Image::printIFDStructure (this=0x644ac0, io=..., out=..., option=Exiv2::kpsRecursive, start=0x8, bSwap=0x0, c=0x49, depth=0x5b) at image.cpp:455
#5  0x00007ffff778218c in Exiv2::Image::printIFDStructure (this=0x644ac0, io=..., out=..., option=Exiv2::kpsRecursive, start=0x8, bSwap=0x0, c=0x49, depth=0x5a) at image.cpp:455
#6  0x00007ffff778218c in Exiv2::Image::printIFDStructure (this=0x644ac0, io=..., out=..., option=Exiv2::kpsRecursive, start=0x8, bSwap=0x0, c=0x49, depth=0x59) at image.cpp:455
#7  0x00007ffff778218c in Exiv2::Image::printIFDStructure (this=0x644ac0, io=..., out=..., option=Exiv2::kpsRecursive, start=0x8, bSwap=0x0, c=0x49, depth=0x58) at image.cpp:455
#8  0x00007ffff778218c in Exiv2::Image::printIFDStructure (this=0x644ac0, io=..., out=..., option=Exiv2::kpsRecursive, start=0x8, bSwap=0x0, c=0x49, depth=0x57) at image.cpp:455
#9  0x00007ffff778218c in Exiv2::Image::printIFDStructure (this=0x644ac0, io=..., out=..., option=Exiv2::kpsRecursive, start=0x8, bSwap=0x0, c=0x49, depth=0x56) at image.cpp:455
#10 0x00007ffff778218c in Exiv2::Image::printIFDStructure (this=0x644ac0, io=..., out=..., option=Exiv2::kpsRecursive, start=0x8, bSwap=0x0, c=0x49, depth=0x55) at image.cpp:455
#11 0x00007ffff778218c in Exiv2::Image::printIFDStructure (this=0x644ac0, io=..., out=..., option=Exiv2::kpsRecursive, start=0x8, bSwap=0x0, c=0x49, depth=0x54) at image.cpp:455
#12 0x00007ffff778218c in Exiv2::Image::printIFDStructure (this=0x644ac0, io=..., out=..., option=Exiv2::kpsRecursive, start=0x8, bSwap=0x0, c=0x49, depth=0x53) at image.cpp:455

===========
the other one : 

Program received signal SIGSEGV, Segmentation fault.
[----------------------------------registers-----------------------------------]
RAX: 0x662000 ('')
RBX: 0x3
RCX: 0x2
RDX: 0x14ff0
RSI: 0x64d010 --> 0x7ffff7082a49 (MemError)
RDI: 0x7fffffffe050 --> 0x7ffff7592e38 --> 0x7ffff735afb0 (<_ZNSt14basic_ofstreamIcSt11char_traitsIcEED1Ev>:    mov    rax,QWORD PTR [rip+0x238d01]        # 0x7ffff7593cb8)
RBP: 0x7fffffffd960 --> 0x7fffffffdb40 --> 0x7fffffffdd20 --> 0x7fffffffdf00 --> 0x7fffffffdf80 --> 0x7fffffffdfe0 (--> ...)
RSP: 0x7fffffffd8a0 --> 0x2f7fe2780
RIP: 0x7ffff778bf41 (<Exiv2::IptcData::printStructure(std::ostream&, unsigned char const*, unsigned long, unsigned int)+111>:   movzx  eax,BYTE PTR [rax])
R8 : 0x644950 --> 0x0
R9 : 0x64d010 --> 0x7ffff7082a49 (MemError)
R10: 0x5e ('^')
R11: 0x246
R12: 0x7ffff78a2ac5 --> 0x4853004949435341 ('ASCII')
R13: 0x7fffffffe490 --> 0x3
R14: 0x0
R15: 0x0
EFLAGS: 0x10206 (carry PARITY adjust zero sign trap INTERRUPT direction overflow)
[-------------------------------------code-------------------------------------]
   0x7ffff778bf31 <Exiv2::IptcData::printStructure(std::ostream&, unsigned char const*, unsigned long, unsigned int)+95>:       mov    edx,DWORD PTR [rbp-0x94]
   0x7ffff778bf37 <Exiv2::IptcData::printStructure(std::ostream&, unsigned char const*, unsigned long, unsigned int)+101>:      mov    rax,QWORD PTR [rbp-0xb0]
   0x7ffff778bf3e <Exiv2::IptcData::printStructure(std::ostream&, unsigned char const*, unsigned long, unsigned int)+108>:      add    rax,rdx
=> 0x7ffff778bf41 <Exiv2::IptcData::printStructure(std::ostream&, unsigned char const*, unsigned long, unsigned int)+111>:      movzx  eax,BYTE PTR [rax]
   0x7ffff778bf44 <Exiv2::IptcData::printStructure(std::ostream&, unsigned char const*, unsigned long, unsigned int)+114>:      cmp    al,0x1c
   0x7ffff778bf46 <Exiv2::IptcData::printStructure(std::ostream&, unsigned char const*, unsigned long, unsigned int)+116>:      jne    0x7ffff778bf14 <Exiv2::IptcData::printStructure(std::ostream&, unsigned char const*, unsigned long, unsigned int)+66>
   0x7ffff778bf48 <Exiv2::IptcData::printStructure(std::ostream&, unsigned char const*, unsigned long, unsigned int)+118>:      add    DWORD PTR [rbp-0xbc],0x1
   0x7ffff778bf4f <Exiv2::IptcData::printStructure(std::ostream&, unsigned char const*, unsigned long, unsigned int)+125>:      mov    edx,DWORD PTR [rbp-0xbc]
[------------------------------------stack-------------------------------------]
0000| 0x7fffffffd8a0 --> 0x2f7fe2780
0008| 0x7fffffffd8a8 --> 0x2
0016| 0x7fffffffd8b0 --> 0x64d010 --> 0x7ffff7082a49 (MemError)
0024| 0x7fffffffd8b8 --> 0x7fffffffe050 --> 0x7ffff7592e38 --> 0x7ffff735afb0 (<_ZNSt14basic_ofstreamIcSt11char_traitsIcEED1Ev>:        mov    rax,QWORD PTR [rip+0x238d01]        # 0x7ffff7593cb8)
0032| 0x7fffffffd8c0 --> 0x0
0040| 0x7fffffffd8c8 --> 0x14ff0f6d39947
0048| 0x7fffffffd8d0 --> 0xd47b0c2
0056| 0x7fffffffd8d8 --> 0x644870 --> 0x7ffffbad2488
[------------------------------------------------------------------------------]
Legend: code, data, rodata, value
Stopped reason: SIGSEGV
0x00007ffff778bf41 in Exiv2::IptcData::printStructure (out=..., bytes=0x64d010 "I*\b\367\377\177", size=0x2, depth=0x2) at iptc.cpp:354
354                     while  ( i < size-3 && bytes[i] != 0x1c ) i++;
gdb-peda$ p bytes
$1 = (const Exiv2::byte *) 0x64d010 "I*\b\367\377\177"
gdb-peda$ x /4w $rax
0x662000:       Cannot access memory at address 0x662000
gdb-peda$ bt
#0  0x00007ffff778bf41 in Exiv2::IptcData::printStructure (out=..., bytes=0x64d010 "I*\b\367\377\177", size=0x2, depth=0x2) at iptc.cpp:354
#1  0x00007ffff7782379 in Exiv2::Image::printIFDStructure (this=0x644ab0, io=..., out=..., option=Exiv2::kpsRecursive, start=0x8, bSwap=0x0, c=0x49, depth=0x2) at image.cpp:470
#2  0x00007ffff778218c in Exiv2::Image::printIFDStructure (this=0x644ab0, io=..., out=..., option=Exiv2::kpsRecursive, start=0x8, bSwap=0x0, c=0x49, depth=0x1) at image.cpp:455
#3  0x00007ffff778218c in Exiv2::Image::printIFDStructure (this=0x644ab0, io=..., out=..., option=Exiv2::kpsRecursive, start=0x8, bSwap=0x0, c=0x49, depth=0x0) at image.cpp:455
#4  0x00007ffff7782abc in Exiv2::Image::printTiffStructure (this=0x644ab0, io=..., out=..., option=Exiv2::kpsRecursive, depth=0xffffffff, offset=0x0) at image.cpp:533
#5  0x00007ffff781bc6d in Exiv2::TiffImage::printStructure (this=0x644ab0, out=..., option=Exiv2::kpsRecursive, depth=0x0) at tiffimage.cpp:344
#6  0x00007ffff781aec3 in Exiv2::TiffImage::readMetadata (this=0x644ab0) at tiffimage.cpp:187
#7  0x000000000041fba6 in Action::Print::printList (this=0x644830) at actions.cpp:537
#8  0x000000000041c76b in Action::Print::run (this=0x644830, path="./crashes-2018-03-23-21-09/exiv2000:id:000015,sig:11,src:000399,op:flip1,pos:26") at actions.cpp:243
#9  0x000000000040e267 in main (argc=0x3, argv=0x7fffffffe498) at exiv2.cpp:166
#10 0x00007ffff6ce9f45 in __libc_start_main (main=0x40dfae <main(int, char* const*)>, argc=0x3, argv=0x7fffffffe498, init=<optimized out>, fini=<optimized out>, rtld_fini=<optimized out>, stack_end=0x7fffffffe488) at libc-start.c:287
#11 0x000000000040dee9 in _start ()
```
==================
the pocs please refer to : 
https://github.com/xiaoqx/pocs/blob/master/exiv2/9-printStructure-outbound-read-1
https://github.com/xiaoqx/pocs/blob/master/exiv2/10-printStructure-outbound-read-2




Comments:
Comment by a17r on 2018-09-21 14:02:51+00:00:
Is this the same as CVE-2017-17724?

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: