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

================= Bug Report (1/1) ==================
## Source: GitHub Issue
## URL: https://github.com/LibRaw/LibRaw/issues/99
## Description:
Issue: LibRaw/LibRaw#99
Title: A Stack Buffer Overflow was discovered in  internal/dcraw_common.cpp
State: closed
Created by: Twi1ight
Created at: 2017-09-08 09:02:39+00:00

Issue Body:
A Stack Buffer Overflow was discovered in  `internal/dcraw_common.cpp:5685`(LibRaw::xtrans_interpolate). It could allow remote denial of service 
 and code execution attack. 

command to reproduce: `./simple_dcraw crash-xtrans_interpolate-stack-overflow`
the latest version is vulnerable. other versions may also be affected.

the sanitizer output:
```
==96836==ERROR: AddressSanitizer: stack-buffer-overflow on address 0x7ffc31555040 at pc 0x7fb90cf370b4 bp 0x7ffc31554f50 sp 0x7ffc31554f48
WRITE of size 4 at 0x7ffc31555040 thread T0
    #0 0x7fb90cf370b3 in LibRaw::xtrans_interpolate(int) /root/Desktop/fuzz/src/LibRaw/internal/dcraw_common.cpp:5836:29
    #1 0x7fb90d230469 in LibRaw::dcraw_process() /root/Desktop/fuzz/src/LibRaw/src/libraw_cxx.cpp:4829:9
    #2 0x514e1e in main /root/Desktop/fuzz/src/LibRaw/samples/simple_dcraw.cpp:159:24
    #3 0x7fb90b9dff44 in __libc_start_main /build/eglibc-SvCtMH/eglibc-2.19/csu/libc-start.c:287
    #4 0x41a6bb in _start (/root/Desktop/fuzz/src/LibRaw/bin/.libs/lt-simple_dcraw+0x41a6bb)

Address 0x7ffc31555040 is located in stack of thread T0 at offset 224 in frame
    #0 0x7fb90cf3192f in LibRaw::xtrans_interpolate(int) /root/Desktop/fuzz/src/LibRaw/internal/dcraw_common.cpp:5686

  This frame has 5 object(s):
    [32, 64) 'hm' (line 5688)
    [96, 112) 'avg' (line 5688)
    [128, 224) 'color' (line 5688) <== Memory access at offset 224 overflows this variable
    [256, 544) 'allhex' (line 5693)
    [608, 632) 'diff' (line 5697)
HINT: this may be a false positive if your program uses some custom stack unwind mechanism or swapcontext
      (longjmp and C++ exceptions *are* supported)
SUMMARY: AddressSanitizer: stack-buffer-overflow /root/Desktop/fuzz/src/LibRaw/internal/dcraw_common.cpp:5836:29 in LibRaw::xtrans_interpolate(int)
Shadow bytes around the buggy address:
  0x1000062a29b0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x1000062a29c0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x1000062a29d0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x1000062a29e0: 00 00 00 00 00 00 00 00 00 00 00 00 f1 f1 f1 f1
  0x1000062a29f0: 00 00 00 00 f2 f2 f2 f2 00 00 f2 f2 00 00 00 00
=>0x1000062a2a00: 00 00 00 00 00 00 00 00[f2]f2 f2 f2 00 00 00 00
  0x1000062a2a10: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x1000062a2a20: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x1000062a2a30: f2 f2 f2 f2 f2 f2 f2 f2 00 00 00 f3 f3 f3 f3 f3
  0x1000062a2a40: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x1000062a2a50: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
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
  Freed heap region:       fd
  Stack left redzone:      f1
  Stack mid redzone:       f2
  Stack right redzone:     f3
  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
  Left alloca redzone:     ca
  Right alloca redzone:    cb
==96836==ABORTING
```

in `internal/dcraw_common.cpp:5688 (xtrans_interpolate)`, color was defined as:
```
  int val, ndir, pass, hm[8], avg[4], color[3][8];
```
with the input testcase in gdb, we could see that the `h` is 3, which leads stack overflow 
```
(gdb) f 2
#2  0x0000000000650838 in LibRaw::xtrans_interpolate (this=0x7ffffff72c60, passes=3) at internal/dcraw_common.cpp:5836
5836	                color[h][d] = g + rix[i << c][h] + rix[-i << c][h];
(gdb) p h
$24 = 3
(gdb) p d
$25 = 0
```


Comments:
Comment by LibRaw on 2017-09-08 09:13:48+00:00:
You have not attach crash-xtrans_interpolate-stack-overflow file 

---

Comment by LibRaw on 2017-09-08 09:27:39+00:00:
Meanwhile this patch should help
[0xtrans-cfa-range.txt](https://github.com/LibRaw/LibRaw/files/1287383/0xtrans-cfa-range.txt)


---

Comment by Twi1ight on 2017-09-08 10:28:26+00:00:
@LibRaw sorry, here it is
[crash-xtrans_interpolate-stack-overflow.zip](https://github.com/LibRaw/LibRaw/files/1287560/crash-xtrans_interpolate-stack-overflow.zip)




---

Comment by LibRaw on 2017-09-08 12:36:54+00:00:
Thanks a log.

Unfortunately 1st patch does not solve this problem (but will solve another one).
Here is addiional CFA pattern check:
[1xtrans-cfa-range.txt](https://github.com/LibRaw/LibRaw/files/1287849/1xtrans-cfa-range.txt)


---

Comment by carnil on 2017-09-12 04:16:29+00:00:
This was assigned [CVE-2017-14265](https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2017-14265)

---

Comment by kirotawa on 2017-09-26 20:42:29+00:00:
Hello there!

Is there any fix available for this issue? 

tks in advance!

---

Comment by LibRaw on 2017-09-27 04:00:10+00:00:
It was fixed in 0.18.3
Current release is 0.18.5

---

Comment by kirotawa on 2017-09-27 12:00:14+00:00:
What is the commit that fix it, do you know?
I want to cherry pick it to fix this CVE in an old version, so can't just jump to the current release right now.

---

Comment by LibRaw on 2017-09-27 14:31:00+00:00:
this one: https://github.com/LibRaw/LibRaw/commit/82616eff4c7f7437e96bdeeed238c3ef3dc12d60



---

Comment by kirotawa on 2017-09-27 17:46:04+00:00:
In this commit has info about CVE-2017-13735 not  CVE-2017-14265. Can I suppose it fix both? 

tks!

---

Comment by LibRaw on 2017-09-27 18:10:33+00:00:
There are two lines in Changelog related to 0.18.3:
* Fix for CVE-2017-13735
* Additional check for X-Trans CFA pattern data

Attachments:
https://github.com/LibRaw/LibRaw/files/1287383/0xtrans-cfa-range.txt
https://github.com/LibRaw/LibRaw/files/1287560/crash-xtrans_interpolate-stack-overflow.zip
https://github.com/LibRaw/LibRaw/files/1287849/1xtrans-cfa-range.txt

Commit References:
82616eff4c7f7437e96bdeeed238c3ef3dc12d60

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 4d2aec21dc76bdf04e66b9dfce0a8442bb3fb375
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;
}