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

================= Bug Report (1/1) ==================
## Source: GitHub Issue
## URL: https://github.com/Exiv2/exiv2/issues/460
## Description:
Issue: Exiv2/exiv2#460
Title: Stack overflow due to excessive stack consumption (Recursive function)
State: closed
Created by: SegfaultMasters
Created at: 2018-09-25 16:06:25+00:00
Labels: bug

Issue Body:
A stack overflow exits in `CiffDirectory::readDirectory()` at `crwimage_int.cpp` due to a recursive function call causing the excessive stack consumption which leads to Denial of service.

 

###### **Affected version:**
exiv2 0.27.0.0 (64 bit build)



###### **Command:**
./exiv2 -pi $POC


### **Debugging**



```
   0x7ffff6f0d35a                  call   0x7ffff6e86bc0 <__stack_chk_fail@plt>
   0x7ffff6f0d35f                  nop    
   0x7ffff6f0d360                  sub    rsp, 0x8
 → 0x7ffff6f0d364                  call   0x7ffff6f06340
   ↳  0x7ffff6f06340                  cmp    BYTE PTR [rip+0x47b341], 0x0        # 0x7ffff7381688
      0x7ffff6f06347                  je     0x7ffff6f06358
      0x7ffff6f06349                  mov    edi, DWORD PTR [rip+0x47b33d]        # 0x7ffff738168c
      0x7ffff6f0634f                  jmp    0x7ffff6e86e00 <pthread_getspecific@plt>
      0x7ffff6f06354                  nop    DWORD PTR [rax+0x0]
      0x7ffff6f06358                  lea    rdx, [rip+0x34986]        # 0x7ffff6f3ace5
```



### ASAN Output

``` 
ASAN:SIGSEGV
=================================================================
==63879==ERROR: AddressSanitizer: stack-overflow on address 0x7ffd1c5e0ff8 (pc 0x7fce8fe99252 bp 0x000000000050 sp 0x7ffd1c5e1000 T0)
    #0 0x7fce8fe99251  (/usr/lib/x86_64-linux-gnu/libasan.so.2+0xb0251)
    #1 0x7fce8fe98d97  (/usr/lib/x86_64-linux-gnu/libasan.so.2+0xafd97)
    #2 0x7fce8fe0bf0f  (/usr/lib/x86_64-linux-gnu/libasan.so.2+0x22f0f)
    #3 0x7fce8fe8255e in operator new(unsigned long) (/usr/lib/x86_64-linux-gnu/libasan.so.2+0x9955e)
    #4 0x7fce8f79c94c in Exiv2::Internal::CiffDirectory::readDirectory(unsigned char const*, unsigned int, Exiv2::ByteOrder) /home/woot/Desktop/exiv2/src/crwimage_int.cpp:292
    #5 0x7fce8f79c733 in Exiv2::Internal::CiffDirectory::doRead(unsigned char const*, unsigned int, unsigned int, Exiv2::ByteOrder) /home/woot/Desktop/exiv2/src/crwimage_int.cpp:269
    #6 0x7fce8f79c318 in Exiv2::Internal::CiffComponent::read(unsigned char const*, unsigned int, unsigned int, Exiv2::ByteOrder) /home/woot/Desktop/exiv2/src/crwimage_int.cpp:227
    #7 0x7fce8f79ca54 in Exiv2::Internal::CiffDirectory::readDirectory(unsigned char const*, unsigned int, Exiv2::ByteOrder) /home/woot/Desktop/exiv2/src/crwimage_int.cpp:296
    #8 0x7fce8f79c733 in Exiv2::Internal::CiffDirectory::doRead(unsigned char const*, unsigned int, unsigned int, Exiv2::ByteOrder) /home/woot/Desktop/exiv2/src/crwimage_int.cpp:269
    #9 0x7fce8f79c318 in Exiv2::Internal::CiffComponent::read(unsigned char const*, unsigned int, unsigned int, Exiv2::ByteOrder) /home/woot/Desktop/exiv2/src/crwimage_int.cpp:227
    #10 0x7fce8f79ca54 in Exiv2::Internal::CiffDirectory::readDirectory(unsigned char const*, unsigned int, Exiv2::ByteOrder) /home/woot/Desktop/exiv2/src/crwimage_int.cpp:296
    #11 0x7fce8f79c733 in Exiv2::Internal::CiffDirectory::doRead(unsigned char const*, unsigned int, unsigned int, Exiv2::ByteOrder) /home/woot/Desktop/exiv2/src/crwimage_int.cpp:269
    #12 0x7fce8f79c318 in Exiv2::Internal::CiffComponent::read(unsigned char const*, unsigned int, unsigned int, Exiv2::ByteOrder) /home/woot/Desktop/exiv2/src/crwimage_int.cpp:227
    #13 0x7fce8f79ca54 in Exiv2::Internal::CiffDirectory::readDirectory(unsigned char const*, unsigned int, Exiv2::ByteOrder) /home/woot/Desktop/exiv2/src/crwimage_int.cpp:296
    #14 0x7fce8f79c733 in Exiv2::Internal::CiffDirectory::doRead(unsigned char const*, unsigned int, unsigned int, Exiv2::ByteOrder) /home/woot/Desktop/exiv2/src/crwimage_int.cpp:269
    #15 0x7fce8f79c318 in Exiv2::Internal::CiffComponent::read(unsigned char const*, unsigned int, unsigned int, Exiv2::ByteOrder) /home/woot/Desktop/exiv2/src/crwimage_int.cpp:227
    #16 0x7fce8f79ca54 in Exiv2::Internal::CiffDirectory::readDirectory(unsigned char const*, unsigned int, Exiv2::ByteOrder) /home/woot/Desktop/exiv2/src/crwimage_int.cpp:296
    #17 0x7fce8f79c733 in Exiv2::Internal::CiffDirectory::doRead(unsigned char const*, unsigned int, unsigned int, Exiv2::ByteOrder) /home/woot/Desktop/exiv2/src/crwimage_int.cpp:269
    #18 0x7fce8f79c318 in Exiv2::Internal::CiffComponent::read(unsigned char const*, unsigned int, unsigned int, Exiv2::ByteOrder) /home/woot/Desktop/exiv2/src/crwimage_int.cpp:227
    #19 0x7fce8f79ca54 in Exiv2::Internal::CiffDirectory::readDirectory(unsigned char const*, unsigned int, Exiv2::ByteOrder) /home/woot/Desktop/exiv2/src/crwimage_int.cpp:296
    #20 0x7fce8f79c733 in Exiv2::Internal::CiffDirectory::doRead(unsigned char const*, unsigned int, unsigned int, Exiv2::ByteOrder) /home/woot/Desktop/exiv2/src/crwimage_int.cpp:269
    #21 0x7fce8f79c318 in Exiv2::Internal::CiffComponent::read(unsigned char const*, unsigned int, unsigned int, Exiv2::ByteOrder) /home/woot/Desktop/exiv2/src/crwimage_int.cpp:227
    #22 0x7fce8f79ca54 in Exiv2::Internal::CiffDirectory::readDirectory(unsigned char const*, unsigned int, Exiv2::ByteOrder) /home/woot/Desktop/exiv2/src/crwimage_int.cpp:296
    #23 0x7fce8f79c733 in Exiv2::Internal::CiffDirectory::doRead(unsigned char const*, unsigned int, unsigned int, Exiv2::ByteOrder) /home/woot/Desktop/exiv2/src/crwimage_int.cpp:269
.
.
.
.
.
.
.
.
    #68 0x7fce8f79c733 in Exiv2::Internal::CiffDirectory::doRead(unsigned char const*, unsigned int, unsigned int, Exiv2::ByteOrder) /home/woot/Desktop/exiv2/src/crwimage_int.cpp:269
    #69 0x7fce8f79c318 in Exiv2::Internal::CiffComponent::read(unsigned char const*, unsigned int, unsigned int, Exiv2::ByteOrder) /home/woot/Desktop/exiv2/src/crwimage_int.cpp:227
    #70 0x7fce8f79ca54 in Exiv2::Internal::CiffDirectory::readDirectory(unsigned char const*, unsigned int, Exiv2::ByteOrder) /home/woot/Desktop/exiv2/src/crwimage_int.cpp:296
    #71 0x7fce8f79c733 in Exiv2::Internal::CiffDirectory::doRead(unsigned char const*, unsigned int, unsigned int, Exiv2::ByteOrder) /home/woot/Desktop/exiv2/src/crwimage_int.cpp:269
    #72 0x7fce8f79c318 in Exiv2::Internal::CiffComponent::read(unsigned char const*, unsigned int, unsigned int, Exiv2::ByteOrder) /home/woot/Desktop/exiv2/src/crwimage_int.cpp:227
    #73 0x7fce8f79ca54 in Exiv2::Internal::CiffDirectory::readDirectory(unsigned char const*, unsigned int, Exiv2::ByteOrder) /home/woot/Desktop/exiv2/src/crwimage_int.cpp:296
    #74 0x7fce8f79c733 in Exiv2::Internal::CiffDirectory::doRead(unsigned char const*, unsigned int, unsigned int, Exiv2::ByteOrder) /home/woot/Desktop/exiv2/src/crwimage_int.cpp:269
    #75 0x7fce8f79c318 in Exiv2::Internal::CiffComponent::read(unsigned char const*, unsigned int, unsigned int, Exiv2::ByteOrder) /home/woot/Desktop/exiv2/src/crwimage_int.cpp:227
    #76 0x7fce8f79ca54 in Exiv2::Internal::CiffDirectory::readDirectory(unsigned char const*, unsigned int, Exiv2::ByteOrder) /home/woot/Desktop/exiv2/src/crwimage_int.cpp:296
    #77 0x7fce8f79c733 in Exiv2::Internal::CiffDirectory::doRead(unsigned char const*, unsigned int, unsigned int, Exiv2::ByteOrder) /home/woot/Desktop/exiv2/src/crwimage_int.cpp:269
    #78 0x7fce8f79c318 in Exiv2::Internal::CiffComponent::read(unsigned char const*, unsigned int, unsigned int, Exiv2::ByteOrder) /home/woot/Desktop/exiv2/src/crwimage_int.cpp:227
    #79 0x7fce8f79ca54 in Exiv2::Internal::CiffDirectory::readDirectory(unsigned char const*, unsigned int, Exiv2::ByteOrder) /home/woot/Desktop/exiv2/src/crwimage_int.cpp:296
    #80 0x7fce8f79c733 in Exiv2::Internal::CiffDirectory::doRead(unsigned char const*, unsigned int, unsigned int, Exiv2::ByteOrder) /home/woot/Desktop/exiv2/src/crwimage_int.cpp:269
    #81 0x7fce8f79c318 in Exiv2::Internal::CiffComponent::read(unsigned char const*, unsigned int, unsigned int, Exiv2::ByteOrder) /home/woot/Desktop/exiv2/src/crwimage_int.cpp:227
    #82 0x7fce8f79ca54 in Exiv2::Internal::CiffDirectory::readDirectory(unsigned char const*, unsigned int, Exiv2::ByteOrder) /home/woot/Desktop/exiv2/src/crwimage_int.cpp:296
    #83 0x7fce8f79c733 in Exiv2::Internal::CiffDirectory::doRead(unsigned char const*, unsigned int, unsigned int, Exiv2::ByteOrder) /home/woot/Desktop/exiv2/src/crwimage_int.cpp:269
    #84 0x7fce8f79c318 in Exiv2::Internal::CiffComponent::read(unsigned char const*, unsigned int, unsigned int, Exiv2::ByteOrder) /home/woot/Desktop/exiv2/src/crwimage_int.cpp:227
    #85 0x7fce8f79ca54 in Exiv2::Internal::CiffDirectory::readDirectory(unsigned char const*, unsigned int, Exiv2::ByteOrder) /home/woot/Desktop/exiv2/src/crwimage_int.cpp:296
    #86 0x7fce8f79c733 in Exiv2::Internal::CiffDirectory::doRead(unsigned char const*, unsigned int, unsigned int, Exiv2::ByteOrder) /home/woot/Desktop/exiv2/src/crwimage_int.cpp:269
    #87 0x7fce8f79c318 in Exiv2::Internal::CiffComponent::read(unsigned char const*, unsigned int, unsigned int, Exiv2::ByteOrder) /home/woot/Desktop/exiv2/src/crwimage_int.cpp:227
    #88 0x7fce8f79ca54 in Exiv2::Internal::CiffDirectory::readDirectory(unsigned char const*, unsigned int, Exiv2::ByteOrder) /home/woot/Desktop/exiv2/src/crwimage_int.cpp:296
    #89 0x7fce8f79c733 in Exiv2::Internal::CiffDirectory::doRead(unsigned char const*, unsigned int, unsigned int, Exiv2::ByteOrder) /home/woot/Desktop/exiv2/src/crwimage_int.cpp:269
    #90 0x7fce8f79c318 in Exiv2::Internal::CiffComponent::read(unsigned char const*, unsigned int, unsigned int, Exiv2::ByteOrder) /home/woot/Desktop/exiv2/src/crwimage_int.cpp:227
    #91 0x7fce8f79ca54 in Exiv2::Internal::CiffDirectory::readDirectory(unsigned char const*, unsigned int, Exiv2::ByteOrder) /home/woot/Desktop/exiv2/src/crwimage_int.cpp:296
    #92 0x7fce8f79c733 in Exiv2::Internal::CiffDirectory::doRead(unsigned char const*, unsigned int, unsigned int, Exiv2::ByteOrder) /home/woot/Desktop/exiv2/src/crwimage_int.cpp:269
    #93 0x7fce8f79c318 in Exiv2::Internal::CiffComponent::read(unsigned char const*, unsigned int, unsigned int, Exiv2::ByteOrder) /home/woot/Desktop/exiv2/src/crwimage_int.cpp:227
    #94 0x7fce8f79ca54 in Exiv2::Internal::CiffDirectory::readDirectory(unsigned char const*, unsigned int, Exiv2::ByteOrder) /home/woot/Desktop/exiv2/src/crwimage_int.cpp:296
    #95 0x7fce8f79c733 in Exiv2::Internal::CiffDirectory::doRead(unsigned char const*, unsigned int, unsigned int, Exiv2::ByteOrder) /home/woot/Desktop/exiv2/src/crwimage_int.cpp:269
    #96 0x7fce8f79c318 in Exiv2::Internal::CiffComponent::read(unsigned char const*, unsigned int, unsigned int, Exiv2::ByteOrder) /home/woot/Desktop/exiv2/src/crwimage_int.cpp:227
    #97 0x7fce8f79ca54 in Exiv2::Internal::CiffDirectory::readDirectory(unsigned char const*, unsigned int, Exiv2::ByteOrder) /home/woot/Desktop/exiv2/src/crwimage_int.cpp:296
    #98 0x7fce8f79c733 in Exiv2::Internal::CiffDirectory::doRead(unsigned char const*, unsigned int, unsigned int, Exiv2::ByteOrder) /home/woot/Desktop/exiv2/src/crwimage_int.cpp:269
    #99 0x7fce8f79c318 in Exiv2::Internal::CiffComponent::read(unsigned char const*, unsigned int, unsigned int, Exiv2::ByteOrder) /home/woot/Desktop/exiv2/src/crwimage_int.cpp:227
    #100 0x7fce8f79ca54 in Exiv2::Internal::CiffDirectory::readDirectory(unsigned char const*, unsigned int, Exiv2::ByteOrder) /home/woot/Desktop/exiv2/src/crwimage_int.cpp:296
    #101 0x7fce8f79c733 in Exiv2::Internal::CiffDirectory::doRead(unsigned char const*, unsigned int, unsigned int, Exiv2::ByteOrder) /home/woot/Desktop/exiv2/src/crwimage_int.cpp:269
    #102 0x7fce8f79c318 in Exiv2::Internal::CiffComponent::read(unsigned char const*, unsigned int, unsigned int, Exiv2::ByteOrder) /home/woot/Desktop/exiv2/src/crwimage_int.cpp:227
    #103 0x7fce8f79ca54 in Exiv2::Internal::CiffDirectory::readDirectory(unsigned char const*, unsigned int, Exiv2::ByteOrder) /home/woot/Desktop/exiv2/src/crwimage_int.cpp:296
    #104 0x7fce8f79c733 in Exiv2::Internal::CiffDirectory::doRead(unsigned char const*, unsigned int, unsigned int, Exiv2::ByteOrder) /home/woot/Desktop/exiv2/src/crwimage_int.cpp:269
.
.
.
.
.
.
.
.
.    #240 0x7fce8f79c318 in Exiv2::Internal::CiffComponent::read(unsigned char const*, unsigned int, unsigned int, Exiv2::ByteOrder) /home/woot/Desktop/exiv2/src/crwimage_int.cpp:227
    #241 0x7fce8f79ca54 in Exiv2::Internal::CiffDirectory::readDirectory(unsigned char const*, unsigned int, Exiv2::ByteOrder) /home/woot/Desktop/exiv2/src/crwimage_int.cpp:296
    #242 0x7fce8f79c733 in Exiv2::Internal::CiffDirectory::doRead(unsigned char const*, unsigned int, unsigned int, Exiv2::ByteOrder) /home/woot/Desktop/exiv2/src/crwimage_int.cpp:269
    #243 0x7fce8f79c318 in Exiv2::Internal::CiffComponent::read(unsigned char const*, unsigned int, unsigned int, Exiv2::ByteOrder) /home/woot/Desktop/exiv2/src/crwimage_int.cpp:227
    #244 0x7fce8f79ca54 in Exiv2::Internal::CiffDirectory::readDirectory(unsigned char const*, unsigned int, Exiv2::ByteOrder) /home/woot/Desktop/exiv2/src/crwimage_int.cpp:296
    #245 0x7fce8f79c733 in Exiv2::Internal::CiffDirectory::doRead(unsigned char const*, unsigned int, unsigned int, Exiv2::ByteOrder) /home/woot/Desktop/exiv2/src/crwimage_int.cpp:269
    #246 0x7fce8f79c318 in Exiv2::Internal::CiffComponent::read(unsigned char const*, unsigned int, unsigned int, Exiv2::ByteOrder) /home/woot/Desktop/exiv2/src/crwimage_int.cpp:227
    #247 0x7fce8f79ca54 in Exiv2::Internal::CiffDirectory::readDirectory(unsigned char const*, unsigned int, Exiv2::ByteOrder) /home/woot/Desktop/exiv2/src/crwimage_int.cpp:296
    #248 0x7fce8f79c733 in Exiv2::Internal::CiffDirectory::doRead(unsigned char const*, unsigned int, unsigned int, Exiv2::ByteOrder) /home/woot/Desktop/exiv2/src/crwimage_int.cpp:269
    #249 0x7fce8f79c318 in Exiv2::Internal::CiffComponent::read(unsigned char const*, unsigned int, unsigned int, Exiv2::ByteOrder) /home/woot/Desktop/exiv2/src/crwimage_int.cpp:227
    #250 0x7fce8f79ca54 in Exiv2::Internal::CiffDirectory::readDirectory(unsigned char const*, unsigned int, Exiv2::ByteOrder) /home/woot/Desktop/exiv2/src/crwimage_int.cpp:296
    #251 0x7fce8f79c733 in Exiv2::Internal::CiffDirectory::doRead(unsigned char const*, unsigned int, unsigned int, Exiv2::ByteOrder) /home/woot/Desktop/exiv2/src/crwimage_int.cpp:269

SUMMARY: AddressSanitizer: stack-overflow ??:0 ??
```


[Reproducer file](https://github.com/SegfaultMasters/covering360/blob/master/Exiv2/readDirectory_stackoverflow_16)



Comments:
Comment by fgeek on 2018-10-02 08:13:17+00:00:
Confirmed in 37b8725565f42c260f9773fe4cfb8fa39f566746 and also reproduced with exiv2json.

---

Comment by clanmills on 2018-10-03 07:57:08+00:00:
Thanks for reporting this @SegfaultMasters And thank you to @fgeek for confirming this.

I have a patch (discussion below) and would like to ask @D4N to review and comment.
```
590 rmills@rmillsmm:~/gnu/github/exiv2/exiv2/build $ git diff
diff --git a/src/crwimage_int.cpp b/src/crwimage_int.cpp
index 4775c37d..053af250 100644
--- a/src/crwimage_int.cpp
+++ b/src/crwimage_int.cpp
@@ -279,6 +279,15 @@ namespace Exiv2 {
         uint32_t o = getULong(pData + size - 4, byteOrder);
         if (size < 2 || o > size-2) throw Error(kerNotACrwImage);
         uint16_t count = getUShort(pData + o, byteOrder);
+#ifdef DEBUG
+        std::cout << "CiffDirectory::readDirectory"
+                  << " size = " << size
+                  << " o = " << o
+                  << " count = " << count
+                  << std::endl;
+#endif
+        // https://github.com/Exiv2/exiv2/issues/460
+        if ( (count * 12) > size ) throw Error(kerNotACrwImage);
 #ifdef DEBUG
         std::cout << "Directory at offset " << std::dec << o
                   <<", " << count << " entries \n";
591 rmills@rmillsmm:~/gnu/github/exiv2/exiv2/build $ 
```

I believe this is a fuzzed CRW file. I don't know the specification for the CRW format, however it's a **_"kind of"_** tiff with directories and data.  The code locates the directory and tests for sanity.  However, the length of the directory is impossible (count == 17736).  The whole buffer is 242 bytes, which has to include count*12 bytes for the directory.

```
CiffDirectory::readDirectory size = 242 o = 0 count = 17736
```

I wondered if the test should include the size of the header, however this causes test/preview-test.sh to fail.
```
        if ( (8+(count * 12)) > size ) throw Error(kerNotACrwImage);
```

`dmpf` is a my home-made utility for dumping files (shows offset, ascii and hex/ascii) similar to `dmpf` on Apollo Computer Aegis OS.

```
591 rmills@rmillsmm:~/gnu/github/exiv2/exiv2/build $ dmpf ~/Downloads/readDirectory_stackoverflow_16.dms 
       0        0: II....HEAPCCDRHE  ->   I  I 0e 00 00 00  H  E  A  P  C  C  D  R  H  E
    0x10       16: A0..............  ->   A  0 c0 00 00 00 00 00 00 00 00 00 00 00 00 00
    0x20       32: ................  ->  00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
... more lines of zeros ...
    0xe0      224: .............t..  ->  00 00 00 00 00 00 00 00 00 00 00 00 00  t 00 00
    0xf0      240: .......0........  ->  00 00 00 00 00 00 00  0 80 00 00 00 00 00 00 00
592 rmills@rmillsmm:~/gnu/github/exiv2/exiv2/build $ 
```
When I build with -DDEBUG, I get:
```
596 rmills@rmillsmm:~/gnu/github/exiv2/exiv2/build $ bin/exiv2 ~/Downloads/readDirectory_stackoverflow_16.dms 
CiffDirectory::readDirectory size = 242 o = 0 count = 17736
Exiv2 exception in print action for file /Users/rmills/Downloads/readDirectory_stackoverflow_16.dms:
This does not look like a CRW image
597 rmills@rmillsmm:~/gnu/github/exiv2/exiv2/build $ bin/exiv2json ~/Downloads/readDirectory_stackoverflow_16.dms 
CiffDirectory::readDirectory size = 242 o = 0 count = 17736
libc++abi.dylib: terminating with uncaught exception of type Exiv2::BasicError<char>: This does not look like a CRW image
Abort trap: 6
598 rmills@rmillsmm:~/gnu/github/exiv2/exiv2/build $ 
```

---

Comment by clanmills on 2018-10-03 08:52:35+00:00:
I've had another look at this.  Several observations (and a new patch):
1)  We must guard the call to getULong() to ensure we have 4 bytes.
2) We must guard the call to getUShort()
3) The directory data seems to have 10 bytes/record
4) Testing inside the loop doesn't work because the recursion can execute
5) By testing before the loop, we detect the infinite recursion and can omit the test inside the loop

```
641 rmills@rmillsmm:~/gnu/github/exiv2/exiv2/build $ git diff
diff --git a/src/crwimage_int.cpp b/src/crwimage_int.cpp
index 4775c37d..c84661e0 100644
--- a/src/crwimage_int.cpp
+++ b/src/crwimage_int.cpp
@@ -276,16 +276,17 @@ namespace Exiv2 {
                                       uint32_t    size,
                                       ByteOrder   byteOrder)
     {
+        if (size < 4) throw Error(kerNotACrwImage);
         uint32_t o = getULong(pData + size - 4, byteOrder);
-        if (size < 2 || o > size-2) throw Error(kerNotACrwImage);
+        if ( o+2 > size ) throw Error(kerNotACrwImage);
         uint16_t count = getUShort(pData + o, byteOrder);
 #ifdef DEBUG
         std::cout << "Directory at offset " << std::dec << o
                   <<", " << count << " entries \n";
 #endif
         o += 2;
+        if ( (o + (count * 10)) > size )  throw Error(kerNotACrwImage);
         for (uint16_t i = 0; i < count; ++i) {
-            if (o + 10 > size) throw Error(kerNotACrwImage);
             uint16_t tag = getUShort(pData + o, byteOrder);
             CiffComponent::AutoPtr m;
             switch (CiffComponent::typeId(tag)) {
642 rmills@rmillsmm:~/gnu/github/exiv2/exiv2/build $ 
```

Commit References:
37b8725565f42c260f9773fe4cfb8fa39f566746

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: