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

Stack out of bounds read in internal/dcraw_common.cpp(kodak_65000_load_raw) #101

Closed
Twi1ight opened this issue Sep 13, 2017 · 8 comments
Closed

Comments

@Twi1ight
Copy link

Command to reproduce: simple_dcraw crash-kodak_65000_load_raw_out-of-bounds-read
crash-kodak_65000_load_raw_out-of-bounds-read.zip

=================================================================
==229209==ERROR: AddressSanitizer: stack-buffer-overflow on address 0x7ffffff73ee2 at pc 0x7ffff778df6e bp 0x7ffffff72730 sp 0x7ffffff72728
READ of size 2 at 0x7ffffff73ee2 thread T0
    #0 0x7ffff778df6d in LibRaw::kodak_65000_load_raw() /root/Desktop/fuzz/src/LibRaw/internal/dcraw_common.cpp:3731:34
    #1 0x7ffff7a96515 in LibRaw::unpack() /root/Desktop/fuzz/src/LibRaw/src/libraw_cxx.cpp:2807:7
    #2 0x52d0a3 in main /root/Desktop/fuzz/src/LibRaw/samples/simple_dcraw.cpp:126:31
    #3 0x7ffff6273f44 in __libc_start_main /build/eglibc-SvCtMH/eglibc-2.19/csu/libc-start.c:287
    #4 0x41b6db in _start (/root/Desktop/fuzz/src/LibRaw/bin/.libs/simple_dcraw+0x41b6db)

Address 0x7ffffff73ee2 is located in stack of thread T0 at offset 1058 in frame
    #0 0x52b7df in main /root/Desktop/fuzz/src/LibRaw/samples/simple_dcraw.cpp:56

  This frame has 3 object(s):
    [32, 1056) 'outfn' (line 60) <== Memory access at offset 1058 overflows this variable
    [1184, 2208) 'thumbfn' (line 60)
    [2336, 566928) 'RawProcessor' (line 62)
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:3731:34 in LibRaw::kodak_65000_load_raw()
Shadow bytes around the buggy address:
  0x10007ffe6780: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x10007ffe6790: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x10007ffe67a0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x10007ffe67b0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x10007ffe67c0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
=>0x10007ffe67d0: 00 00 00 00 00 00 00 00 00 00 00 00[f2]f2 f2 f2
  0x10007ffe67e0: f2 f2 f2 f2 f2 f2 f2 f2 f2 f2 f2 f2 00 00 00 00
  0x10007ffe67f0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x10007ffe6800: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x10007ffe6810: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x10007ffe6820: 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
==229209==ABORTING

gdb debug output:

(gdb) bt
#0  0x00000000004fdc04 in __asan::ReportGenericError(unsigned long, unsigned long, unsigned long, unsigned long, bool, unsigned long, unsigned int, bool) ()
#1  0x00000000004fe9f3 in __asan_report_load2 ()
#2  0x00007ffff778df6e in LibRaw::kodak_65000_load_raw (this=0x7ffffff743e0) at internal/dcraw_common.cpp:3731
#3  0x00007ffff7a96516 in LibRaw::unpack (this=0x7ffffff743e0) at src/libraw_cxx.cpp:2807
#4  0x000000000052d0a4 in main (ac=2, av=0x7fffffffe3a8) at samples/simple_dcraw.cpp:126
(gdb) f 2
#2  0x00007ffff778df6e in LibRaw::kodak_65000_load_raw (this=0x7ffffff743e0) at internal/dcraw_common.cpp:3731
3731	        if ((RAW(row, col + i) = curve[ret ? buf[i] : (pred[i & 1] += buf[i])]) >> 12)
(gdb) p ret ? buf[i] : (pred[i & 1] += buf[i])
$5 = -544416
(gdb) p pred
$6 = {-544416, 32767}
(gdb) p buf[i]
$7 = 17376
(gdb) 

we could see that the index of curve is a large negative number -544416, leads out of bounds read.

@LibRaw
Copy link
Owner

LibRaw commented Sep 13, 2017

Thanks.
Could you please guys

  1. accumulate multiple errors before reporting to CVE team
  2. Coordinate with another team (CVE-2017-14348 Heap buffer overflow in LibRaw::processCanonCameraInfo #100 )
    ?
    It is not hard to publish new patches every day, but too much trouble to publish full release 3rd time a week.

LibRaw deals with data come from external sources and the data format(s) are complex and not well defined. So, it is very likely that we have lot of such bugs.

So, it is much better to create single CVE (multiple vulns in ...) but not separate version/separate CVE for each patch.

@LibRaw
Copy link
Owner

LibRaw commented Sep 13, 2017

Fixed in d13e8f6

@LibRaw LibRaw closed this as completed Sep 13, 2017
@pgajdos
Copy link

pgajdos commented Sep 15, 2017

With 0.18.4 and above example I get:

$ valgrind simple_dcraw crash-kodak_65000_load_raw_out-of-bounds-read
==24943== Memcheck, a memory error detector
==24943== Copyright (C) 2002-2017, and GNU GPL'd, by Julian Seward et al.
==24943== Using Valgrind-3.13.0 and LibVEX; rerun with -h for copyright info
==24943== Command: simple_dcraw crash-kodak_65000_load_raw_out-of-bounds-read
==24943==
crash-kodak_65000_load_raw_out-of-bounds-read: data corrupted at 782348
==24943== Invalid read of size 2
==24943== at 0x4E609E0: LibRaw::kodak_65000_load_raw() (dcraw_common.cpp:3244)
==24943== by 0x4EA9989: LibRaw::unpack() (libraw_cxx.cpp:2523)
==24943== by 0x400F74: main (simple_dcraw.cpp:131)
==24943== Address 0x1ffef9ebca is on thread 1's stack
==24943== 726 bytes below stack pointer
==24943==
==24943==
==24943== Process terminating with default action of signal 11 (SIGSEGV): dumping core
==24943== Access not within mapped region at address 0x1FFEF9AFA8
==24943== at 0x4E609E0: LibRaw::kodak_65000_load_raw() (dcraw_common.cpp:3244)
==24943== by 0x4EA9989: LibRaw::unpack() (libraw_cxx.cpp:2523)
==24943== by 0x400F74: main (simple_dcraw.cpp:131)
==24943== If you believe this happened as a result of a stack
==24943== overflow in your program's main thread (unlikely but
==24943== possible), you can try to increase the size of the
==24943== main thread stack using the --main-stacksize= flag.
==24943== The main thread stack size used in this run was 8388608.
==24943==
==24943== HEAP SUMMARY:
==24943== in use at exit: 27,568,990 bytes in 8 blocks
==24943== total heap usage: 25 allocs, 17 frees, 27,643,443 bytes allocated
==24943==
==24943== LEAK SUMMARY:
==24943== definitely lost: 0 bytes in 0 blocks
==24943== indirectly lost: 0 bytes in 0 blocks
==24943== possibly lost: 0 bytes in 0 blocks
==24943== still reachable: 27,568,990 bytes in 8 blocks
==24943== suppressed: 0 bytes in 0 blocks
==24943== Rerun with --leak-check=full to see details of leaked memory
==24943==
==24943== For counts of detected and suppressed errors, rerun with: -v
==24943== ERROR SUMMARY: 65 errors from 1 contexts (suppressed: 0 from 0)
Segmentation fault (core dumped)
$

@LibRaw
Copy link
Owner

LibRaw commented Sep 15, 2017

Have you applied patch d13e8f6 ?

@pgajdos
Copy link

pgajdos commented Sep 15, 2017

Eh, of course not. I read the difference of the change log wrongly. I am sorry for noise.

@LibRaw
Copy link
Owner

LibRaw commented Sep 15, 2017

BTW, it needs more patch(es), it is possible to run out of buf[256], will fix today

@pgajdos
Copy link

pgajdos commented Oct 18, 2017

With 0.18.5, I do not get segfault anymore. However, there are many valgrind errors:

$ valgrind --quiet simple_dcraw crash-kodak_65000_load_raw_out-of-bounds-read
crash-kodak_65000_load_raw_out-of-bounds-read: data corrupted at 725440
==29012== Conditional jump or move depends on uninitialised value(s)
==29012==    at 0x4E61A18: LibRaw::kodak_65000_load_raw() (dcraw_common.cpp:3245)
==29012==    by 0x4EAA999: LibRaw::unpack() (libraw_cxx.cpp:2523)
==29012==    by 0x400F74: main (simple_dcraw.cpp:131)
==29012== 
==29012== Use of uninitialised value of size 8
==29012==    at 0x4E619C7: LibRaw::kodak_65000_load_raw() (dcraw_common.cpp:3247)
==29012==    by 0x4EAA999: LibRaw::unpack() (libraw_cxx.cpp:2523)
==29012==    by 0x400F74: main (simple_dcraw.cpp:131)
==29012== 
==29012== 
==29012== More than 10000000 total errors detected.  I'm not reporting any more.
==29012== Final error counts will be inaccurate.  Go fix your program!
==29012== Rerun with --error-limit=no to disable this cutoff.  Note
==29012== that errors may occur in your program without prior warning from
==29012== Valgrind, because errors are no longer being displayed.
==29012==
$

@LibRaw
Copy link
Owner

LibRaw commented Oct 18, 2017

these jumps are limited by curve input range

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

3 participants