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

================= Bug Report (1/1) ==================
## Source: GitHub Issue
## URL: https://github.com/Exiv2/exiv2/issues/168
## Description:
Issue: Exiv2/exiv2#168
Title: CVE-2017-18005: NULL Pointer Dereference while extracting metadata of a malformed tiff
State: closed
Created by: kirit1193
Created at: 2017-11-18 22:24:23+00:00

Issue Body:
There's a NULL Pointer Dereference occurring during the metadata extraction from a malformed tiff file.
This can be triggered by running `./exiv2 -v pr -P EIXxgklnycsvth %file%` on the test-case, [exiv2-nullpointerderef.zip](https://github.com/Exiv2/exiv2/files/1485071/exiv2-nullpointerderef.zip).

The hexdump of the test-case is:

```
0000000 4949 002a 0050 0000 3030 3030 3030 3030
0000010 3030 3030 3030 3030 3030 3030 3030 3030
*
0000050 000f 0117 0006 0030 0000 3030 3030 3030
0000060 0003 0030 0000 3030 3030 3030 0002 0030
0000070 0000 3030 3030 3030 000b 0030 0000 3030
0000080 3030 3030 000b 0030 0000 3030 3030 3030
0000090 000b 0030 0000 3030 3030 3030 000b 0030
00000a0 0000 3030 3030 3030 0003 0030 0000 3030
00000b0 3030 3030 000b 0030 0000 3030 3030 3030
00000c0 000b 0030 0000 3030 3030 3030 000a 0000
00000d0 0000 3030 3030 3030 000b 0030 0000 3030
00000e0 3030 3030 000b 0030 0000 3030 3030 3030
00000f0 0003 0030 0000 3030 3030 3030 000c 0000
0000100 0000 3030 3030 0000 0000
0000109
```

The relevant ASAN output is:

```
==4728==ERROR: AddressSanitizer: SEGV on unknown address 0x000000000000 (pc 0x557dc0c47468 bp 0x7fff7558bbb0 sp 0x7fff7558bbb0 T0)
==4728==The signal is caused by a READ memory access.
==4728==Hint: address points to the zero page.
    #0 0x557dc0c47467 in Exiv2::DataValue::toLong(long) const /home/ksg/exiv2/src/value.cpp:250
    #1 0x557dc0688058 in Action::Print::printMetadatum(Exiv2::Metadatum const&, Exiv2::Image const*) /home/ksg/exiv2/src/actions.cpp:731
    #2 0x557dc068bad2 in Action::Print::printMetadata(Exiv2::Image const*) /home/ksg/exiv2/src/actions.cpp:552
    #3 0x557dc068d61a in Action::Print::printList() /home/ksg/exiv2/src/actions.cpp:541
    #4 0x557dc06b8fff in Action::Print::run(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&) /home/ksg/exiv2/src/actions.cpp:245
    #5 0x557dc05983a6 in main /home/ksg/exiv2/src/exiv2.cpp:170
    #6 0x7f2987d301c0 in __libc_start_main (/lib/x86_64-linux-gnu/libc.so.6+0x211c0)
    #7 0x557dc0621b59 in _start (/home/ksg/testbench/exiv2_asan+0x22bb59)
```
It looks like the NULL-Pointer Dereference is being triggered by a 0 value which is being used in the toLong function in the value of **n**, which is being dereferenced in 

```return value_[n];```

This is indicated by the GDB backtrace:

```
Program received signal SIGSEGV, Segmentation fault.
Exiv2::DataValue::toLong (this=0x55555609d860, n=0) at value.cpp:250
250             return value_[n];
(gdb) bt
#0  Exiv2::DataValue::toLong (this=0x55555609d860, n=0) at value.cpp:250
#1  0x000055555561d5f1 in Action::Print::printMetadatum (this=this@entry=0x555556092e70, md=..., pImage=pImage@entry=0x555556093530) at actions.cpp:731
#2  0x000055555561ecf0 in Action::Print::printMetadata (this=this@entry=0x555556092e70, image=image@entry=0x555556093530) at actions.cpp:552
#3  0x000055555561f2fb in Action::Print::printList (this=this@entry=0x555556092e70) at actions.cpp:541
#4  0x00005555556313c8 in Action::Print::run (this=0x555556092e70, path="/home/ksg/exif-crashes/npd") at actions.cpp:245
#5  0x00005555555bc339 in main (argc=<optimized out>, argv=<optimized out>) at exiv2.cpp:170
```

Debug info:

Exiv2 version 0.26 001a00 (64 bit build)
Compiler: gcc 7.2, clang 4.0.1-6
OS: Ubuntu 17.10


Comments:
Comment by D4N on 2017-11-19 20:35:34+00:00:
Thanks for the report. However I can neither reproduce this with the master branch or with the 0.26 branch (that is version 0.26 + backported security fixes). Could you try your reproducer against those two branches and report back if the issue is resolved?

---

Comment by kirit1193 on 2017-11-20 14:15:22+00:00:
I found this issue on the master branch, git-cloned from this repository.
Are you not getting any error while running exiv2 against this reproducer? I just confirmed by running it again on the attached file after unzipping it.

---

Comment by D4N on 2017-11-20 15:16:24+00:00:
You are right, apparently I did not properly cleanup the
repository. Your file also triggers a different kind of crash with
exiv2json, so I suspect that the bug is triggered somewhere else.

Anyway, I'll take a look at this.


---

Comment by kirit1193 on 2017-11-20 18:18:23+00:00:
Very interesting, let me check out the crash with exiv2json.
Do let me know if I can help you further with any triage.

---

Comment by D4N on 2017-11-20 23:37:21+00:00:
At least with exiv2json the culprit is probably the function which reads in the image metadata or one of the following functions, as the crash occurs due to a std::vector with zero capacity being dereferenced unsafely. This will probably be trickier than I was hoping.

---

Comment by kirit1193 on 2017-12-16 04:35:04+00:00:
Hey was this fixed?

---

Comment by D4N on 2017-12-16 09:21:16+00:00:
No, sorry not yet. I didn't have the time to debug this further, as I am currently working on some improvements under the hood. I hope to take a look at this issue soon, but I can't promise a certain date.

If you think that this is more important (e.g. because you can actively exploit this), please tell me (in the case of an active exploit, please do so via email).

---

Comment by carnil on 2018-01-01 09:24:18+00:00:
This issue has been assigned CVE-2017-18005

---

Comment by D4N on 2018-01-01 09:27:07+00:00:
FYI this will be fixed by #199

---

Comment by D4N on 2018-03-21 09:00:02+00:00:
#199 has been merged

Attachments:
https://github.com/Exiv2/exiv2/files/1485071/exiv2-nullpointerderef.zip

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: