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

================= Bug Report (1/1) ==================
## Source: GitHub Issue
## URL: https://github.com/LibRaw/LibRaw/issues/100
## Description:
Issue: LibRaw/LibRaw#100
Title: CVE-2017-14348 Heap buffer overflow in LibRaw::processCanonCameraInfo
State: closed
Created by: fgeek
Created at: 2017-09-12 06:43:06+00:00

Issue Body:
Sample: http://bugs.fi/media/afl/libraw/libraw-0.18.3-heap-buffer-overflow-processCanonCameraInfo.cr2
Credit: Henri Salo from Nixu Corporation
Tools: afl-2.51b, afl-utils, GCC AddressSanitizer
~~~
./raw-identify 3cf207558915d72a1a77ae9c8ed55b7496c2131e
=================================================================
==12072==ERROR: AddressSanitizer: heap-buffer-overflow on address 0x60200000ee31 at pc 0x7febd8ff396d bp 0x7ffc53c69e20 sp 0x7ffc53c69e18
WRITE of size 1 at 0x60200000ee31 thread T0
    #0 0x7febd8ff396c in LibRaw::processCanonCameraInfo(unsigned int, unsigned char*, unsigned int) internal/dcraw_common.cpp:5892
    #1 0x7febd9046da9 in LibRaw::parse_makernote(int, int) internal/dcraw_common.cpp:8330
    #2 0x7febd905de27 in LibRaw::parse_exif(int) internal/dcraw_common.cpp:9836
    #3 0x7febd902f3fd in LibRaw::parse_tiff_ifd(int) internal/dcraw_common.cpp:10717
    #4 0x7febd90342c1 in LibRaw::parse_tiff_ifd(int) internal/dcraw_common.cpp:10550
    #5 0x7febd90342c1 in LibRaw::parse_tiff_ifd(int) internal/dcraw_common.cpp:10550
    #6 0x7febd90342c1 in LibRaw::parse_tiff_ifd(int) internal/dcraw_common.cpp:10550
    #7 0x7febd90342c1 in LibRaw::parse_tiff_ifd(int) internal/dcraw_common.cpp:10550
    #8 0x7febd90342c1 in LibRaw::parse_tiff_ifd(int) internal/dcraw_common.cpp:10550
    #9 0x7febd90342c1 in LibRaw::parse_tiff_ifd(int) internal/dcraw_common.cpp:10550
    #10 0x7febd90342c1 in LibRaw::parse_tiff_ifd(int) internal/dcraw_common.cpp:10550
    #11 0x7febd90342c1 in LibRaw::parse_tiff_ifd(int) internal/dcraw_common.cpp:10550
    #12 0x7febd90342c1 in LibRaw::parse_tiff_ifd(int) internal/dcraw_common.cpp:10550
    #13 0x7febd903d7ea in LibRaw::parse_tiff(int) internal/dcraw_common.cpp:11254
    #14 0x7febd908b0cc in LibRaw::identify() internal/dcraw_common.cpp:14124
    #15 0x7febd91b26c6 in LibRaw::open_datastream(LibRaw_abstract_datastream*) src/libraw_cxx.cpp:1737
    #16 0x7febd91be1b2 in LibRaw::open_file(char const*, long long) src/libraw_cxx.cpp:972
    #17 0x4016a9 in main samples/raw-identify.cpp:141
    #18 0x7febd781db44 in __libc_start_main (/lib/x86_64-linux-gnu/libc.so.6+0x21b44)
    #19 0x408459 (/home/afl/builds/libraw/0.18.3/bin/raw-identify+0x408459)

0x60200000ee31 is located 0 bytes to the right of 1-byte region [0x60200000ee30,0x60200000ee31)
allocated by thread T0 here:
    #0 0x7febd94cb73f in malloc (/usr/lib/x86_64-linux-gnu/libasan.so.1+0x5473f)
    #1 0x7febd915b15b in libraw_memmgr::malloc(unsigned long) libraw/libraw_alloc.h:39
    #2 0x7febd915b15b in LibRaw::malloc(unsigned long) src/libraw_cxx.cpp:475
    #3 0x7febd9045d5e in LibRaw::parse_makernote(int, int) internal/dcraw_common.cpp:8316
    #4 0x7febd905de27 in LibRaw::parse_exif(int) internal/dcraw_common.cpp:9836
    #5 0x7febd902f3fd in LibRaw::parse_tiff_ifd(int) internal/dcraw_common.cpp:10717
    #6 0x7febd90342c1 in LibRaw::parse_tiff_ifd(int) internal/dcraw_common.cpp:10550
    #7 0x7febd90342c1 in LibRaw::parse_tiff_ifd(int) internal/dcraw_common.cpp:10550
    #8 0x7febd90342c1 in LibRaw::parse_tiff_ifd(int) internal/dcraw_common.cpp:10550
    #9 0x7febd90342c1 in LibRaw::parse_tiff_ifd(int) internal/dcraw_common.cpp:10550
    #10 0x7febd90342c1 in LibRaw::parse_tiff_ifd(int) internal/dcraw_common.cpp:10550
    #11 0x7febd90342c1 in LibRaw::parse_tiff_ifd(int) internal/dcraw_common.cpp:10550
    #12 0x7febd90342c1 in LibRaw::parse_tiff_ifd(int) internal/dcraw_common.cpp:10550
    #13 0x7febd90342c1 in LibRaw::parse_tiff_ifd(int) internal/dcraw_common.cpp:10550
    #14 0x7febd90342c1 in LibRaw::parse_tiff_ifd(int) internal/dcraw_common.cpp:10550
    #15 0x7febd903d7ea in LibRaw::parse_tiff(int) internal/dcraw_common.cpp:11254
    #16 0x7febd908b0cc in LibRaw::identify() internal/dcraw_common.cpp:14124
    #17 0x7febd91b26c6 in LibRaw::open_datastream(LibRaw_abstract_datastream*) src/libraw_cxx.cpp:1737
    #18 0x7febd91be1b2 in LibRaw::open_file(char const*, long long) src/libraw_cxx.cpp:972
    #19 0x4016a9 in main samples/raw-identify.cpp:141
    #20 0x7febd781db44 in __libc_start_main (/lib/x86_64-linux-gnu/libc.so.6+0x21b44)

SUMMARY: AddressSanitizer: heap-buffer-overflow internal/dcraw_common.cpp:5892 LibRaw::processCanonCameraInfo(unsigned int, unsigned char*, unsigned int)
Shadow bytes around the buggy address:
  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 fa fa
  0x0c047fff9db0: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
=>0x0c047fff9dc0: fa fa fa fa fa fa[01]fa fa fa 00 07 fa fa fd fd
  0x0c047fff9dd0: fa fa fd fd 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 00 fa
  0x0c047fff9e00: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x0c047fff9e10: 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
  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
  Contiguous container OOB:fc
  ASan internal:           fe
==12072==ABORTING
~~~


Comments:
Comment by LibRaw on 2017-09-12 06:45:36+00:00:
thanks

---

Comment by LibRaw on 2017-09-12 07:23:20+00:00:
Fixed in 0.18.4 (pushed to github just now)

---

Comment by fgeek on 2017-09-12 19:34:13+00:00:
Please use CVE-2017-14348 for this issue.

---

Comment by LibRaw on 2017-09-13 04:17:31+00:00:
Guys,
could you please
1) coordinate with another team (https://github.com/LibRaw/LibRaw/issues/101)
2) create single CVE for multiple problems (e.g. once a week, multiple problems in LibRaw)...

It is not hard to patch source every day and publish patches, but too much hassle to publish complete release (distro bundles) every day. I prefer weekly schedule:
 - accumulate patches
 - publish once a week (or two)
 - and publish CVE once a week (or two) too.
Not everyday.

These bugs are important, but not a very big hurry because no one (AFAIK) run LibRaw on random files come from net from anonymous users. 

---

Comment by LibRaw on 2017-09-13 06:32:47+00:00:
CVE and credits are noted in last push

https://github.com/LibRaw/LibRaw/commit/d13e8f6d1e987b7491182040a188c16a395f1d21

---

Comment by Twi1ight on 2017-09-13 09:16:13+00:00:
@LibRaw OK, I will submit bugs once a week later.

---

Comment by carnil on 2017-09-15 18:43:13+00:00:
The fix for this issue should be 8303e74b0567806dd5f16fc39aab70fe928de1a2

---

Comment by LibRaw on 2017-09-15 18:52:57+00:00:
yes

---

Comment by LibRaw on 2017-09-15 18:53:29+00:00:
https://github.com/LibRaw/LibRaw/issues/100#issuecomment-328763717


Commit References:
3cf207558915d72a1a77ae9c8ed55b7496c2131e
d13e8f6d1e987b7491182040a188c16a395f1d21
8303e74b0567806dd5f16fc39aab70fe928de1a2

Build script:
#!/bin/bash -eu
# Minimized build script with only core build commands
set -eu
./configure --disable-examples
make -j$(nproc)

Dockerfile:
FROM hwiwonlee/secb.base:latest
RUN apt-get update && apt-get install -y make autoconf automake libtool pkg-config
RUN git clone https://github.com/libraw/libraw libraw
RUN git -C libraw checkout 82616eff4c7f7437e96bdeeed238c3ef3dc12d60
WORKDIR $SRC/libraw
COPY build.sh $SRC/

Additional files:
filename: libraw_fuzzer.cc
content: /*  Copyright 2020 Google Inc.

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

      http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/

#include <stddef.h>
#include <stdint.h>

#include <string>

#include <libraw.h>

extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) {
  // Input less than 10mb
  if (size > 10000000) {
    return 0;
  }

  LibRaw lib_raw;

  int result = lib_raw.open_buffer(
      const_cast<char*>(reinterpret_cast<const char*>(data)), size);
  if (result != LIBRAW_SUCCESS) {
    return 0;
  }

  result = lib_raw.unpack();
  if (result != LIBRAW_SUCCESS) {
    return 0;
  }

  result = lib_raw.dcraw_process();
  if (result != LIBRAW_SUCCESS) {
    return 0;
  }

  return 0;
}