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

================= Bug Report (1/1) ==================
## Source: GitHub Issue
## URL: https://github.com/LibRaw/LibRaw/issues/400
## Description:
Issue: LibRaw/LibRaw#400
Title: stack-buffer-over in libRaw
State: closed
Created by: gtt1995
Created at: 2021-04-12 03:06:49+00:00

Issue Body:

[poc-libRaw.zip](https://github.com/LibRaw/LibRaw/files/6293598/poc-libRaw.zip)
Reproduce step :
compile libraw with Address sanitizer
run cmd : ./libraw_cr2_fuzzer poc
### INFO: Running with entropic power schedule (0xFF, 100).
INFO: Seed: 3355647081
INFO: Loaded 1 modules   (18101 inline 8-bit counters): 18101 [0xb3b730, 0xb3fde5),
INFO: Loaded 1 PC tables (18101 PCs): 18101 [0x815158,0x85bca8),
./libraw_cr2_fuzzer: Running 1 inputs 1 time(s) each.
Running: crash-5f77e83098892cb416521525ef399068c83941fe
=================================================================
==173755==ERROR: AddressSanitizer: stack-buffer-overflow on address 0x7ffc443b133f at pc 0x0000005b1375 bp 0x7ffc443b1260 sp 0x7ffc443b1258
WRITE of size 1 at 0x7ffc443b133f thread T0
    #0 0x5b1374  (/home/gtt/out/build/libfuzzer-latest-average/libraw/libraw_cr2_fuzzer+0x5b1374)
    #1 0x6e29f0  (/home/gtt/out/build/libfuzzer-latest-average/libraw/libraw_cr2_fuzzer+0x6e29f0)
    #2 0x6b0d68  (/home/gtt/out/build/libfuzzer-latest-average/libraw/libraw_cr2_fuzzer+0x6b0d68)
    #3 0x6bf88c  (/home/gtt/out/build/libfuzzer-latest-average/libraw/libraw_cr2_fuzzer+0x6bf88c)
    #4 0x663f0e  (/home/gtt/out/build/libfuzzer-latest-average/libraw/libraw_cr2_fuzzer+0x663f0e)
    #5 0x598252  (/home/gtt/out/build/libfuzzer-latest-average/libraw/libraw_cr2_fuzzer+0x598252)
    #6 0x59735a  (/home/gtt/out/build/libfuzzer-latest-average/libraw/libraw_cr2_fuzzer+0x59735a)
    #7 0x4c916a  (/home/gtt/out/build/libfuzzer-latest-average/libraw/libraw_cr2_fuzzer+0x4c916a)
    #8 0x5179e6  (/home/gtt/out/build/libfuzzer-latest-average/libraw/libraw_cr2_fuzzer+0x5179e6)
    #9 0x4c9d9f  (/home/gtt/out/build/libfuzzer-latest-average/libraw/libraw_cr2_fuzzer+0x4c9d9f)
    #10 0x4d7e93  (/home/gtt/out/build/libfuzzer-latest-average/libraw/libraw_cr2_fuzzer+0x4d7e93)
    #11 0x4c9417  (/home/gtt/out/build/libfuzzer-latest-average/libraw/libraw_cr2_fuzzer+0x4c9417)
    #12 0x7fc5fb3df0b2  (/lib/x86_64-linux-gnu/libc.so.6+0x270b2)
    #13 0x41e908  (/home/gtt/out/build/libfuzzer-latest-average/libraw/libraw_cr2_fuzzer+0x41e908)

Address 0x7ffc443b133f is located in stack of thread T0 at offset 95 in frame
    #0 0x6e080f  (/home/gtt/out/build/libfuzzer-latest-average/libraw/libraw_cr2_fuzzer+0x6e080f)

  This frame has 7 object(s):
    [32, 36) 'tag' (line 64)
    [48, 52) 'type' (line 64)
    [64, 68) 'len' (line 64)
    [80, 84) 'save' (line 64)
    [96, 608) 'mn_text' (line 219) <== Memory access at offset 95 underflows this variable
    [672, 1184) 'ccms' (line 221)
    [1248, 1256) 'last' (line 253)
HINT: this may be a false positive if your program uses some custom stack unwind mechanism, swapcontext or vfork
      (longjmp and C++ exceptions *are* supported)
SUMMARY: AddressSanitizer: stack-buffer-overflow (/home/gtt/out/build/libfuzzer-latest-average/libraw/libraw_cr2_fuzzer+0x5b1374)
Shadow bytes around the buggy address:
  0x10000886e210: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x10000886e220: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x10000886e230: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x10000886e240: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x10000886e250: 00 00 00 00 00 00 00 00 00 00 00 00 f1 f1 f1 f1
=>0x10000886e260: 04 f2 04 f2 04 f2 04[f2]00 00 00 00 00 00 00 00
  0x10000886e270: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x10000886e280: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x10000886e290: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x10000886e2a0: 00 00 00 00 00 00 00 00 f2 f2 f2 f2 f2 f2 f2 f2
  0x10000886e2b0: 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
  Shadow gap:              cc
==173755==ABORTING


Comments:
Comment by alextutubalin on 2021-04-12 05:57:14+00:00:
Could not reproduce the problem.
Is there any chance to get stack trace with source information (source code line or, at least, function name).

Also, please specify exact LibRaw version used (commit ID or so)

---

Comment by gtt1995 on 2021-04-12 07:31:49+00:00:
Sorry.
Here is some additional information. If you have any other questions, please comment.
The version is the latest git repo: [(https://github.com/LibRaw/LibRaw.git)]

==============This is stack trace:

(gdb) r
Starting program: /home/gtt/out/build/libfuzzer-latest-average/libraw/libraw_fuzzer poc-libraw-libraw_cr2_fuzzer
[Thread debugging using libthread_db enabled]
Using host libthread_db library "/lib/x86_64-linux-gnu/libthread_db.so.1".
INFO: Running with entropic power schedule (0xFF, 100).
INFO: Seed: 2746983604
INFO: Loaded 1 modules   (18101 inline 8-bit counters): 18101 [0xb3b730, 0xb3fde5),
INFO: Loaded 1 PC tables (18101 PCs): 18101 [0x815158,0x85bca8),
[New Thread 0x7ffff2ef9700 (LWP 175905)]
/home/gtt/out/build/libfuzzer-latest-average/libraw/libraw_fuzzer: Running 1 inputs 1 time(s) each.
Running: poc-libraw-libraw_cr2_fuzzer

Thread 1 "libraw_fuzzer" hit Breakpoint 1, LibRaw::parse_tiff_ifd(int) () at src/metadata/tiff.cpp:758
758	in src/metadata/tiff.cpp
(gdb) bt
#0  LibRaw::parse_tiff_ifd(int) () at src/metadata/tiff.cpp:758
#1  0x00000000006bf88d in LibRaw::parse_tiff(int) () at src/metadata/tiff.cpp:1495
#2  0x0000000000663f0f in LibRaw::identify() () at src/metadata/identify.cpp:503
#3  0x0000000000598253 in LibRaw::open_datastream(LibRaw_abstract_datastream*) () at src/utils/open.cpp:464
#4  0x000000000059735b in LibRaw::open_buffer(void const*, unsigned long) () at src/utils/open.cpp:227
#5  0x00000000004c916b in LLVMFuzzerTestOneInput () at /src/libraw_fuzzer.cc:41
#6  0x00000000005179e7 in ExecuteCallback () at /src/glibfuzzer/FuzzerLoop.cpp:605
#7  0x00000000004c9da0 in RunOneTest () at /src/glibfuzzer/FuzzerDriver.cpp:323
#8  0x00000000004d7e94 in FuzzerDriver () at /src/glibfuzzer/FuzzerDriver.cpp:856
#9  0x00000000004c9418 in main () at /src/glibfuzzer/FuzzerMain.cpp:20
(gdb)


=================This is **GDB** info:


(gdb) r
The program being debugged has been started already.
Start it from the beginning? (y or n) y
Starting program: /home/gtt/out/build/libfuzzer-latest-average/libraw/libraw_fuzzer ./crash-5f77e83098892cb416521525ef399068c83941fe
[Thread debugging using libthread_db enabled]
Using host libthread_db library "/lib/x86_64-linux-gnu/libthread_db.so.1".
INFO: Running with entropic power schedule (0xFF, 100).
INFO: Seed: 1759319609
INFO: Loaded 1 modules   (18101 inline 8-bit counters): 18101 [0xb3b730, 0xb3fde5),
INFO: Loaded 1 PC tables (18101 PCs): 18101 [0x815158,0x85bca8),
[New Thread 0x7ffff2ef9700 (LWP 175762)]
/home/gtt/out/build/libfuzzer-latest-average/libraw/libraw_fuzzer: Running 1 inputs 1 time(s) each.
Running: ./crash-5f77e83098892cb416521525ef399068c83941fe
_
Thread 1 "libraw_fuzzer" hit Breakpoint 1, LibRaw::open_buffer(void const*, unsigned long) () at src/utils/open.cpp:226
226	src/utils/open.cpp: 没有那个文件或目录.
(gdb) c
Continuing.

Thread 1 "libraw_fuzzer" hit Breakpoint 2, LibRaw::identify() () at src/metadata/identify.cpp:410
410	src/metadata/identify.cpp: 没有那个文件或目录.
(gdb) c
Continuing.

Thread 1 "libraw_fuzzer" hit Breakpoint 3, LibRaw::identify() () at src/metadata/identify.cpp:477
477	in src/metadata/identify.cpp
(gdb) c
Continuing.

Thread 1 "libraw_fuzzer" hit Breakpoint 4, LibRaw::identify() () at src/metadata/identify.cpp:503
503	in src/metadata/identify.cpp
(gdb) c
Continuing.

Thread 1 "libraw_fuzzer" hit Breakpoint 5, LibRaw::parse_tiff(int) () at src/metadata/tiff.cpp:1495
1495	src/metadata/tiff.cpp: 没有那个文件或目录.
(gdb) c
Continuing.

Thread 1 "libraw_fuzzer" hit Breakpoint 8, LibRaw::parse_tiff_ifd(int) () at src/metadata/tiff.cpp:757
757	in src/metadata/tiff.cpp
(gdb) c
Continuing.

Thread 1 "libraw_fuzzer" hit Breakpoint 9, LibRaw::parse_tiff_ifd(int) () at src/metadata/tiff.cpp:758
758	in src/metadata/tiff.cpp
(gdb) c
Continuing.

Thread 1 "libraw_fuzzer" hit Breakpoint 10, LibRaw::parse_exif(int) () at src/metadata/exif_gps.cpp:73
73	src/metadata/exif_gps.cpp: 没有那个文件或目录.
(gdb) b src/metadata/tiff.cpp:759
Breakpoint 15 at 0x6b09d0: file **src/metadata/tiff.cpp, line 763**.
(gdb) c
Continuing._

=================================================================
==175761==ERROR: AddressSanitizer: stack-buffer-overflow on address 0x7ffffff3d39f at pc 0x0000005b1375 bp 0x7ffffff3d2c0 sp 0x7ffffff3d2b8
WRITE of size 1 at 0x7ffffff3d39f thread T0
    #0 0x5b1374  (/home/gtt/out/build/libfuzzer-latest-average/libraw/libraw_fuzzer+0x5b1374)
    #1 0x6e29f0  (/home/gtt/out/build/libfuzzer-latest-average/libraw/libraw_fuzzer+0x6e29f0)
    #2 0x6b0d68  (/home/gtt/out/build/libfuzzer-latest-average/libraw/libraw_fuzzer+0x6b0d68)
    #3 0x6bf88c  (/home/gtt/out/build/libfuzzer-latest-average/libraw/libraw_fuzzer+0x6bf88c)
    #4 0x663f0e  (/home/gtt/out/build/libfuzzer-latest-average/libraw/libraw_fuzzer+0x663f0e)
    #5 0x598252  (/home/gtt/out/build/libfuzzer-latest-average/libraw/libraw_fuzzer+0x598252)
    #6 0x59735a  (/home/gtt/out/build/libfuzzer-latest-average/libraw/libraw_fuzzer+0x59735a)
    #7 0x4c916a  (/home/gtt/out/build/libfuzzer-latest-average/libraw/libraw_fuzzer+0x4c916a)
    #8 0x5179e6  (/home/gtt/out/build/libfuzzer-latest-average/libraw/libraw_fuzzer+0x5179e6)
    #9 0x4c9d9f  (/home/gtt/out/build/libfuzzer-latest-average/libraw/libraw_fuzzer+0x4c9d9f)
    #10 0x4d7e93  (/home/gtt/out/build/libfuzzer-latest-average/libraw/libraw_fuzzer+0x4d7e93)
    #11 0x4c9417  (/home/gtt/out/build/libfuzzer-latest-average/libraw/libraw_fuzzer+0x4c9417)
    #12 0x7ffff7c500b2  (/lib/x86_64-linux-gnu/libc.so.6+0x270b2)
    #13 0x41e908  (/home/gtt/out/build/libfuzzer-latest-average/libraw/libraw_fuzzer+0x41e908)

Address 0x7ffffff3d39f is located in stack of thread T0 at offset 95 in frame
    #0 0x6e080f  (/home/gtt/out/build/libfuzzer-latest-average/libraw/libraw_fuzzer+0x6e080f)

  This frame has 7 object(s):
    [32, 36) 'tag' (line 64)
    [48, 52) 'type' (line 64)
    [64, 68) 'len' (line 64)
    [80, 84) 'save' (line 64)
    [96, 608) 'mn_text' (line 219) <== Memory access at offset 95 underflows this variable
    [672, 1184) 'ccms' (line 221)
    [1248, 1256) 'last' (line 253)
HINT: this may be a false positive if your program uses some custom stack unwind mechanism, swapcontext or vfork
      (longjmp and C++ exceptions *are* supported)
SUMMARY: AddressSanitizer: stack-buffer-overflow (/home/gtt/out/build/libfuzzer-latest-average/libraw/libraw_fuzzer+0x5b1374)
Shadow bytes around the buggy address:
  0x10007ffdfa20: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x10007ffdfa30: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x10007ffdfa40: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x10007ffdfa50: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x10007ffdfa60: 00 00 00 00 00 00 00 00 f1 f1 f1 f1 04 f2 04 f2
=>0x10007ffdfa70: 04 f2 04[f2]00 00 00 00 00 00 00 00 00 00 00 00
  0x10007ffdfa80: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x10007ffdfa90: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x10007ffdfaa0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x10007ffdfab0: 00 00 00 00 f2 f2 f2 f2 f2 f2 f2 f2 00 00 00 00
  0x10007ffdfac0: 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
  Shadow gap:              cc
==175761==ABORTING
[Thread 0x7ffff2ef9700 (LWP 175762) exited]
[Inferior 1 (process 175761) exited with code 01]
(gdb)




---

Comment by alextutubalin on 2021-04-12 07:43:51+00:00:
Sorry, your reply/gdb backtracr does not make things clear

Initial report refers to mn_text variable.
Your reply mentions src/metadata/exif_gps.cpp:73 where this variable is not defined (it is local).

I do not see any possibility to access mn_text with negative offsets.

Things are still not clear.



---

Comment by gtt1995 on 2021-04-12 07:46:02+00:00:
Sorry,
I just updated the comment.

---

Comment by gtt1995 on 2021-04-12 07:48:32+00:00:
Hello,Friend~

---

Comment by alextutubalin on 2021-04-12 07:52:24+00:00:
Is there any chance to see what exact line of code underflows mn_text variable?

---

Comment by gtt1995 on 2021-04-12 08:49:13+00:00:
Sorry,I am not very good at gdb tools.

Running: projects/libraw/poc
=================================================================
==175051==ERROR: AddressSanitizer: stack-buffer-overflow on address 0x7ffeb21459ff at pc 0x00000058a035 bp 0x7ffeb2145920 sp 0x7ffeb2145918
WRITE of size 1 at 0x7ffeb21459ff thread T0
    #0 0x58a034 in LibRaw_buffer_datastream::gets(char*, int) /src/libraw/src/libraw_datastream.cpp:288  ,tips:maybe in the function
    #1 0x6bb6b0 in LibRaw::parse_exif(int) /src/libraw/src/metadata/exif_gps.cpp:225:9
    #2 0x689a28 in LibRaw::parse_tiff_ifd(int) /src/libraw/src/metadata/tiff.cpp:758:7
    #3 0x69854c in LibRaw::parse_tiff(int) /src/libraw/src/metadata/tiff.cpp:1495:9
    #4 0x63cbce in LibRaw::identify() /src/libraw/src/metadata/identify.cpp:503:14
    #5 0x570f12 in LibRaw::open_datastream(LibRaw_abstract_datastream*) /src/libraw/src/utils/open.cpp:464:4
    #6 0x57001a in LibRaw::open_buffer(void const*, unsigned long) /src/libraw/src/utils/open.cpp:227:13
    #7 0x54ff2a in LLVMFuzzerTestOneInput /src/libraw_fuzzer.cc:41:24
    #8 0x458af1 in fuzzer::Fuzzer::ExecuteCallback(unsigned char const*, unsigned long) /src/llvm-project/compiler-rt/lib/fuzzer/FuzzerLoop.cpp:558:15
    #9 0x444262 in fuzzer::RunOneTest(fuzzer::Fuzzer*, char const*, unsigned long) /src/llvm-project/compiler-rt/lib/fuzzer/FuzzerDriver.cpp:296:6
    #10 0x44a28e in fuzzer::FuzzerDriver(int*, char***, int (*)(unsigned char const*, unsigned long)) /src/llvm-project/compiler-rt/lib/fuzzer/FuzzerDriver.cpp:796:9
    #11 0x471cc2 in main /src/llvm-project/compiler-rt/lib/fuzzer/FuzzerMain.cpp:19:10
    #12 0x7f7eab7710b2 in __libc_start_main /build/glibc-eX1tMB/glibc-2.31/csu/../csu/libc-start.c:308:16
    #13 0x41e748 in _start (/workspace/oss-fuzz/build/out/libraw/libraw_cr2_fuzzer+0x41e748)

Address 0x7ffeb21459ff is located in stack of thread T0 at offset 95 in frame
    #0 0x6b94cf in LibRaw::parse_exif(int) /src/libraw/src/metadata/exif_gps.cpp:63

  This frame has 7 object(s):
    [32, 36) 'tag' (line 64)
    [48, 52) 'type' (line 64)
    [64, 68) 'len' (line 64)
    [80, 84) 'save' (line 64)
    [96, 608) 'mn_text' (line 219) <== Memory access at offset 95 underflows this variable
    [672, 1184) 'ccms' (line 221)
    [1248, 1256) 'last' (line 253)
HINT: this may be a false positive if your program uses some custom stack unwind mechanism, swapcontext or vfork
      (longjmp and C++ exceptions *are* supported)
SUMMARY: AddressSanitizer: stack-buffer-overflow /src/libraw/src/libraw_datastream.cpp in LibRaw_buffer_datastream::gets(char*, int)
Shadow bytes around the buggy address:
  0x100056420ae0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x100056420af0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x100056420b00: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x100056420b10: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x100056420b20: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
=>0x100056420b30: 00 00 00 00 f1 f1 f1 f1 04 f2 04 f2 04 f2 04[f2]
  0x100056420b40: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x100056420b50: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x100056420b60: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x100056420b70: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x100056420b80: f2 f2 f2 f2 f2 f2 f2 f2 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
  Shadow gap:              cc
==175051==ABORTING



---

Comment by alextutubalin on 2021-04-12 08:58:58+00:00:
Thanks.
So, it points to https://github.com/LibRaw/LibRaw/blob/master/src/metadata/exif_gps.cpp#L225

I'm still unable to understand how this may result into buffer underflow.

Also: could you please specify EXACT LibRaw version you're testing (commit ID or something like that)

---

Comment by gtt1995 on 2021-04-12 09:03:58+00:00:
OK.
The version is latest git repo

This is my Dockerfile:

FROM gcr.io/oss-fuzz-base/base-builder
 18 RUN apt-get update && apt-get install -y make autoconf automake libtool pkg-config
 19 RUN git clone --depth 1 https://github.com/libraw/libraw
 20 WORKDIR libraw
 21 
 22 ADD http://oss-fuzz-corpus.storage.googleapis.com/libraw/libraw_cr2_fuzzer_seed_corpus.zip $SRC/
 23 ADD http://oss-fuzz-corpus.storage.googleapis.com/libraw/libraw_nef_fuzzer_seed_corpus.zip $SRC/
 24 ADD http://oss-fuzz-corpus.storage.googleapis.com/libraw/libraw_raf_fuzzer_seed_corpus.zip $SRC/
 25 
 26 COPY build.sh libraw_fuzzer.cc $SRC/


---

Comment by alextutubalin on 2021-04-12 09:09:47+00:00:
No I do not. Please assign it yourself if you need it.



---

Comment by alextutubalin on 2021-04-12 09:20:45+00:00:
I do not know, please deal with it yourself.

I'm still unable to reproduce the problem using POC file you provided and LibRaw/latest-github with gcc11 -fsanitize=address.
Looks very like to false positive for me.
Also, the source code line pointed by your comment is not able to produce buffer underflow, it is just reading from input stream into variable.

---

Comment by gtt1995 on 2021-04-12 09:26:44+00:00:
thanks.
Maybe you should reproduce it by oss-fuzz/projects/libraw/dockerfile,build.sh,libraw_fuzzer.cc. [https://github.com/google/oss-fuzz/blob/master/projects/libraw/Dockerfile](url)

---

Comment by alextutubalin on 2021-04-12 09:30:05+00:00:
This circus is too complex for me.
All real bugs are reproducible with just a debugger, even without ASAN.
This one is not. gcc11/ASAN does not helps too.

So, I put it on hold unless someone reproduces the problem and explain it to us.

---

Comment by gtt1995 on 2021-04-12 09:39:34+00:00:
thanks, I will try it later.

---

Comment by gtt1995 on 2021-04-12 10:07:36+00:00:
this is built with afl 
INFO:
======================= INFO =========================
This binary is built for AFL-fuzz.
To run the target function on individual input(s) execute this:
  ./build/out/libraw/libraw_cr2_fuzzer < INPUT_FILE
or
  ./build/out/libraw/libraw_cr2_fuzzer INPUT_FILE1 [INPUT_FILE2 ... ]
To fuzz with afl-fuzz execute this:
  afl-fuzz [afl-flags] ./build/out/libraw/libraw_cr2_fuzzer [-N]
afl-fuzz will run N iterations before re-spawning the process (default: 1000)
======================================================
Reading 290705 bytes from projects/libraw/poc
=================================================================
==202933==ERROR: AddressSanitizer: stack-buffer-overflow on address 0x7fff7984d15f at pc 0x00000050195d bp 0x7fff7984d080 sp 0x7fff7984d078
WRITE of size 1 at 0x7fff7984d15f thread T0
    #0 0x50195c in LibRaw_buffer_datastream::gets(char*, int) /src/libraw/src/libraw_datastream.cpp
    #1 0x617124 in LibRaw::parse_exif(int) /src/libraw/src/metadata/exif_gps.cpp:225:9
    #2 0x5e8df8 in LibRaw::parse_tiff_ifd(int) /src/libraw/src/metadata/tiff.cpp:758:7
    #3 0x5f6eed in LibRaw::parse_tiff(int) /src/libraw/src/metadata/tiff.cpp:1495:9
    #4 0x59ff6f in LibRaw::identify() /src/libraw/src/metadata/identify.cpp:503:14
    #5 0x4e997f in LibRaw::open_datastream(LibRaw_abstract_datastream*) /src/libraw/src/utils/open.cpp:464:4
    #6 0x4e8b51 in LibRaw::open_buffer(void const*, unsigned long) /src/libraw/src/utils/open.cpp:227:13
    #7 0x4c8d00 in LLVMFuzzerTestOneInput /src/libraw_fuzzer.cc:41:24
    #8 0x4c92ce in ExecuteFilesOnyByOne /src/libfuzzer/afl/afl_driver.cpp:217:5
    #9 0x4c92ce in main /src/libfuzzer/afl/afl_driver.cpp:254:12
    #10 0x7f637d3df0b2 in __libc_start_main /build/glibc-eX1tMB/glibc-2.31/csu/../csu/libc-start.c:308:16
    #11 0x41e4b8 in _start (/workspace/oss-fuzz/build/out/libraw/libraw_cr2_fuzzer+0x41e4b8)

Address 0x7fff7984d15f is located in stack of thread T0 at offset 95 in frame
    #0 0x61528f in LibRaw::parse_exif(int) /src/libraw/src/metadata/exif_gps.cpp:63

  This frame has 7 object(s):
    [32, 36) 'tag' (line 64)
    [48, 52) 'type' (line 64)
    [64, 68) 'len' (line 64)
    [80, 84) 'save' (line 64)
    [96, 608) 'mn_text' (line 219) <== Memory access at offset 95 underflows this variable
    [672, 1184) 'ccms' (line 221)
    [1248, 1256) 'last' (line 253)
HINT: this may be a false positive if your program uses some custom stack unwind mechanism, swapcontext or vfork
      (longjmp and C++ exceptions *are* supported)
SUMMARY: AddressSanitizer: stack-buffer-overflow /src/libraw/src/libraw_datastream.cpp in LibRaw_buffer_datastream::gets(char*, int)
Shadow bytes around the buggy address:
  0x10006f3019d0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x10006f3019e0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x10006f3019f0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x10006f301a00: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x10006f301a10: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
=>0x10006f301a20: f1 f1 f1 f1 04 f2 04 f2 04 f2 04[f2]00 00 00 00
  0x10006f301a30: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x10006f301a40: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x10006f301a50: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x10006f301a60: 00 00 00 00 00 00 00 00 00 00 00 00 f2 f2 f2 f2
  0x10006f301a70: f2 f2 f2 f2 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
  Shadow gap:              cc
==202933==ABORTING


---

Comment by alextutubalin on 2021-04-12 10:27:23+00:00:
Much much clearer now, thanks.

This patch should fix it: https://github.com/LibRaw/LibRaw/commit/bc3aaf4223fdb70d52d470dae65c5a7923ea2a49

---

Comment by gtt1995 on 2021-04-12 10:28:21+00:00:
yeah!
thanks for your time very much!

---

Comment by LibRaw on 2021-05-01 17:54:09+00:00:
closed

Attachments:
https://github.com/LibRaw/LibRaw/files/6293598/poc-libRaw.zip

Commit References:
bc3aaf4223fdb70d52d470dae65c5a7923ea2a49
5f77e83098892cb416521525ef399068c83941fe

Build script:
#!/bin/bash -eu
# Minimized build script with only core build commands
set -eu
autoreconf --install
./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 1dbed6b7e65ef2ebd0c3f82722a0b7f3990845f7
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>

enum InterpolationOptions {
  Linear = 0,
  Vng = 1, 
  Ppg = 2,
  Ahd = 3,
  Dcb = 4,
  Dht = 11,
  AhdModified = 12
};

extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) {
  // Input less than 15mb
  if (size > 15000000) {
    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;
  }

  InterpolationOptions options[] = {Linear, Vng, Ppg, Ahd, Dcb, Dht, AhdModified};

  for (int i = 0; i < sizeof(options)/sizeof(*options); i++) {
    lib_raw.output_params_ptr()->user_qual = static_cast<int>(options[i]);

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

  return 0;
}