Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

It exists heap-buffer-overflow when use function raw2image() #195

Closed
fantasyoung opened this issue Dec 21, 2018 · 11 comments
Closed

It exists heap-buffer-overflow when use function raw2image() #195

fantasyoung opened this issue Dec 21, 2018 · 11 comments

Comments

@fantasyoung
Copy link

Description

It exists heap-buffer-overflow in LibRaw::raw2image() src/libraw_cxx.cpp:3423

My test program

4channels in Libraw/bin

Command and argument

./4channels 4channels_crash

Crash Information

The output of exampletest with address sanitizer enabled

==98918==ERROR: AddressSanitizer: heap-buffer-overflow on address 0x62800000b900 at pc 0x7f498eedbe62 bp 0x7fff93fa5040 sp 0x7fff93fa47e8
WRITE of size 208 at 0x62800000b900 thread T0
    #0 0x7f498eedbe61 in __asan_memmove (/usr/lib/x86_64-linux-gnu/libasan.so.2+0x8ce61)
    #1 0x42aae0 in LibRaw::raw2image() src/libraw_cxx.cpp:3423
    #2 0x404824 in main samples/4channels.cpp:110
    #3 0x7f498db6c82f in __libc_start_main (/lib/x86_64-linux-gnu/libc.so.6+0x2082f)
    #4 0x403df8 in _start (/home/wind/libraw_fuzz_new/as_libraw_7e29b/LibRaw-7e29b9f29449fde30cc878fbb137d61c14bba3a4/bin/4channels+0x403df8)

0x62800000b900 is located 0 bytes to the right of 14336-byte region [0x628000008100,0x62800000b900)
allocated by thread T0 here:
    #0 0x7f498eee779a in __interceptor_calloc (/usr/lib/x86_64-linux-gnu/libasan.so.2+0x9879a)
    #1 0x455d8f in libraw_memmgr::calloc(unsigned long, unsigned long) libraw/libraw_alloc.h:56
    #2 0x410458 in LibRaw::calloc(unsigned long, unsigned long) src/libraw_cxx.cpp:557
    #3 0x429b34 in LibRaw::raw2image() src/libraw_cxx.cpp:3369
    #4 0x404824 in main samples/4channels.cpp:110
    #5 0x7f498db6c82f in __libc_start_main (/lib/x86_64-linux-gnu/libc.so.6+0x2082f)

SUMMARY: AddressSanitizer: heap-buffer-overflow ??:0 __asan_memmove
Shadow bytes around the buggy address:
  0x0c507fff96d0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x0c507fff96e0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x0c507fff96f0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x0c507fff9700: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x0c507fff9710: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
=>0x0c507fff9720:[fa]fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x0c507fff9730: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x0c507fff9740: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x0c507fff9750: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x0c507fff9760: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x0c507fff9770: 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
  Container overflow:      fc
  Array cookie:            ac
  Intra object redzone:    bb
  ASan internal:           fe
==98918==ABORTING

Version

the commit is 7e29b9f

POC File

crash.zip

CREDIT

pu!m,Weiran Labs

@LibRaw
Copy link
Owner

LibRaw commented Dec 21, 2018

OK, for strange reason I see only partial patch (previous one) in raw2image, will revisit github copy today.

@carnil
Copy link

carnil commented Dec 22, 2018

This is CVE-2018-20365

@LibRaw
Copy link
Owner

LibRaw commented Dec 24, 2018

CVE-2018-20363, CVE-2018-20364, CVE-2018-20365 - all three are assigned for the same problem

@carnil
Copy link

carnil commented Dec 24, 2018 via email

@LibRaw
Copy link
Owner

LibRaw commented Dec 24, 2018

I see single problem: due to inconsistency in Sinar 4-shot files handling (introduced in current development branch), it is possible to read full-color data in one place, while try to read single-color data in another.
This requires two similar fixes in raw2image() and raw2image_ex() calls.
Because of my inattention, there are two separate patches for each fix (and both patches was reworked today).

Please note

  1. LibRaw 0.19 (stable) seems to not be affected by this specific problem because there is no Sinar 4-shot handling in this version. So, only development branch looks affected.
  2. however, the fix was backported to 0.19-branch to prevent similar problems (if any).

Also, in #193 discussion I see traces of some another problem, but I do not have POC (and I'm not sure that reporter has recompiled LibRaw after git pull).

Right now I assume that sinar-4-shot related case (all three CVEs) is resolved.

@LibRaw LibRaw closed this as completed Dec 24, 2018
@carnil
Copy link

carnil commented Dec 24, 2018

thanks for the detailed reply. With 0.19.1 (currently in Debian unstable) I see for the case of #193 reproducer:

Starting program: /usr/lib/libraw/4channels /home/build/0000
[Thread debugging using libthread_db enabled]
Using host libthread_db library "/lib/x86_64-linux-gnu/libthread_db.so.1".
Processing file /home/build/0000

Program received signal SIGSEGV, Segmentation fault.
0x00007ffff7f4b2a0 in LibRaw::raw2image (this=this@entry=0x7ffffff74730)
    at src/libraw_cxx.cpp:3229
3229                imgdata.image[((row) >> IO.shrink) * S.iwidth + ((col) >> IO.shrink)][fcol(row, col)] =
(gdb) bt
#0  0x00007ffff7f4b2a0 in LibRaw::raw2image (this=this@entry=0x7ffffff74730)
    at src/libraw_cxx.cpp:3229
#1  0x000055555555529f in main (ac=2, av=0x7fffffffebd8) at samples/4channels.cpp:110
(gdb) list
3224          else
3225          {
3226            int row, col;
3227            for (row = 0; row < S.height; row++)
3228              for (col = 0; col < S.width; col++)
3229                imgdata.image[((row) >> IO.shrink) * S.iwidth + ((col) >> IO.shrink)][fcol(row, col)] =
3230                    imgdata.rawdata.raw_image[(row + S.top_margin) * S.raw_pitch / 2 + (col + S.left_margin)];
3231          }
3232        }
3233        else // if(decoder_info.decoder_flags & LIBRAW_DECODER_LEGACY)
(gdb)

@LibRaw
Copy link
Owner

LibRaw commented Dec 24, 2018

This sample is refused under windows (my primary dev. env), as it should.

Anyway, master-branch fix is backported to 0.19.2, so 0.19.2 should process it safely (tested w/ FreeBSD, sorry no Linux here).

@pgajdos
Copy link

pgajdos commented Jan 8, 2019

Apologize, what commit actually is supposed to fix this issue?

With 0.19.2 I get for given testcase:

(gdb) run
Starting program: /usr/bin/4channels 4channels_crash
Processing file 4channels_crash
=================================================================
==25914==ERROR: AddressSanitizer: heap-buffer-overflow on address 0x628000003900 at pc 0x7ffff704976e bp 0x7ffffff740b0 sp 0x7ffffff73860
WRITE of size 208 at 0x628000003900 thread T0
    #0 0x7ffff704976d in __interceptor_memmove (/usr/lib64/libasan.so.5+0x3a76d)
    #1 0x7ffff6f1f7b1 in LibRaw::raw2image() (/usr/lib64/libraw.so.19+0x1cc7b1)
    #2 0x401ea7  (/usr/bin/4channels+0x401ea7)
    #3 0x7ffff69b5fea in __libc_start_main (/lib64/libc.so.6+0x22fea)
    #4 0x401249  (/usr/bin/4channels+0x401249)

0x628000003900 is located 0 bytes to the right of 14336-byte region [0x628000000100,0x628000003900)
allocated by thread T0 here:
    #0 0x7ffff70fb0b8 in calloc (/usr/lib64/libasan.so.5+0xec0b8)
    #1 0x7ffff6f4d565 in libraw_memmgr::calloc(unsigned long, unsigned long) (/usr/lib64/libraw.so.19+0x1fa565)
    #2 0x7ffff6f0351a in LibRaw::calloc(unsigned long, unsigned long) (/usr/lib64/libraw.so.19+0x1b051a)
    #3 0x7ffff6f1e519 in LibRaw::raw2image() (/usr/lib64/libraw.so.19+0x1cb519)
    #4 0x401ea7  (/usr/bin/4channels+0x401ea7)
    #5 0x7ffff69b5fea in __libc_start_main (/lib64/libc.so.6+0x22fea)

SUMMARY: AddressSanitizer: heap-buffer-overflow (/usr/lib64/libasan.so.5+0x3a76d) in __interceptor_memmove
Shadow bytes around the buggy address:
  0x0c507fff86d0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x0c507fff86e0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x0c507fff86f0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x0c507fff8700: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x0c507fff8710: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
=>0x0c507fff8720:[fa]fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x0c507fff8730: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x0c507fff8740: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x0c507fff8750: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x0c507fff8760: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x0c507fff8770: 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
  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
==25914==ABORTING

Program received signal SIGABRT, Aborted.
0x00007ffff69cb08b in raise () from /lib64/libc.so.6
(gdb) bt
#0  0x00007ffff69cb08b in raise () from /lib64/libc.so.6
#1  0x00007ffff69b44e9 in abort () from /lib64/libc.so.6
#2  0x00007ffff711835b in ?? () from /usr/lib64/libasan.so.5
#3  0x00007ffff71203e8 in ?? () from /usr/lib64/libasan.so.5
#4  0x00007ffff710555d in ?? () from /usr/lib64/libasan.so.5
#5  0x00007ffff7049793 in memmove () from /usr/lib64/libasan.so.5
#6  0x00007ffff6f1f7b2 in LibRaw::raw2image (this=0x7ffffff74320) at src/libraw_cxx.cpp:3242
#7  0x0000000000401ea8 in main (ac=2, av=0x7fffffffe848) at samples/4channels.cpp:110
(gdb) frame 6
#6  0x00007ffff6f1f7b2 in LibRaw::raw2image (this=0x7ffffff74320) at src/libraw_cxx.cpp:3242
3242	            memmove(&imgdata.image[row * S.width],
(gdb) l
3237	        if (S.width * 8 == S.raw_pitch)
3238	          memmove(imgdata.image, imgdata.rawdata.color4_image, S.width * S.height * sizeof(*imgdata.image));
3239	        else
3240	        {
3241	          for (int row = 0; row < S.height; row++)
3242	            memmove(&imgdata.image[row * S.width],
3243	                    &imgdata.rawdata.color4_image[(row + S.top_margin) * S.raw_pitch / 8 + S.left_margin],
3244	                    S.width * sizeof(*imgdata.image));
3245	        }
3246
(gdb)

@LibRaw
Copy link
Owner

LibRaw commented Jan 9, 2019

OK, got it.
It is another problem, but from same POC: it is possible to trick raw2image/raw2image_ex to do half-size allocation (and than buffer overrun) even for full-color input data for Sinar 4-shot files.

@LibRaw
Copy link
Owner

LibRaw commented Jan 10, 2019

This patch should fix it: a7c17cb

I do not consider this problem as serious as the original one, because it affects only half_size=1 case.

@pgajdos
Copy link

pgajdos commented Jan 10, 2019

This patch on top of 0.19.2 fixes the issue.
Thanks for your fast response!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants