dropbox / lepton

Lepton is a tool and file format for losslessly compressing JPEGs by an average of 22%.
https://blogs.dropbox.com/tech/2016/07/lepton-image-compression-saving-22-losslessly-from-images-at-15mbs/
Apache License 2.0
5.01k stars 355 forks source link

Some memory corruptions in lepton #26

Closed marcograss closed 8 years ago

marcograss commented 8 years ago

Hi, I at this url you can download some samples that will cause memory corruption problems in lepton:

https://github.com/marcograss/marcograss.github.io/blob/master/assets/lepton_testcases1.zip?raw=true

you can reproduce with ./lepton/lepton -singlethread -unjailed -preload testcase.jpeg /tmp/out.lep

  1. unknown.jpeg

lepton v1.0-91619e2 START ACHIEVED 1468716163 822728 decode error in scan0 / mcu2TS_MAIN (0) 0.000000 TS_MODEL_INIT_BEGIN (0) 0.004525 TS_MODEL_INIT (0) 0.004543 TS_READ_STARTED (0) 0.004637 TS_READ_FINISHED (0) 0.004768 TS_JPEG_DECODE_STARTED (0) 0.004768 TS_JPEG_DECODE_FINISHED (0) 0.004975 TS_DONE (0) 0.004976 6573388 bytes needed to decompress this file

::::BILL::::

==76344==ERROR: AddressSanitizer: unknown-crash on address 0x0000008cb038 at pc 0x00000052eb79 bp 0x7ffd0cfd5720 sp 0x7ffd0cfd5710 READ of size 208 at 0x0000008cb038 thread T0

0 0x52eb78 in std::__atomic_base::load(std::memory_order) const /usr/include/c++/6/bits/atomic_base.h:396

#1 0x52eb78 in std::__atomic_base<unsigned int>::operator unsigned int() const /usr/include/c++/6/bits/atomic_base.h:259
#2 0x52eb78 in print_bill(int) src/vp8/util/billing.cc:145
#3 0x46b7f3 in process_file(IOUtil::FileReader_, IOUtil::FileWriter_, int, bool) src/lepton/jpgcoder.cc:1616
#4 0x406c73 in main src/lepton/jpgcoder.cc:773
#5 0x7effabc9182f in __libc_start_main (/lib/x86_64-linux-gnu/libc.so.6+0x2082f)
#6 0x40afc8 in _start (/home/marco/VulnResearch/misc/lepton/lepton+0x40afc8)

0x0000008cb090 is located 0 bytes to the right of global variable 'billing_map' defined in 'src/vp8/util/billing.cc:10:23' (0x8cafc0) of size 208 SUMMARY: AddressSanitizer: unknown-crash /usr/include/c++/6/bits/atomic_base.h:396 in std::__atomic_base::load(std::memory_order) const Shadow bytes around the buggy address: 0x0000801115b0: 04 f9 f9 f9 f9 f9 f9 f9 04 f9 f9 f9 f9 f9 f9 f9 0x0000801115c0: 04 f9 f9 f9 f9 f9 f9 f9 04 f9 f9 f9 f9 f9 f9 f9 0x0000801115d0: 04 f9 f9 f9 f9 f9 f9 f9 04 f9 f9 f9 f9 f9 f9 f9 0x0000801115e0: 04 f9 f9 f9 f9 f9 f9 f9 04 f9 f9 f9 f9 f9 f9 f9 0x0000801115f0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 =>0x000080111600: 00 00 00 00 00 00 00[00]00 00 00 00 00 00 00 00 0x000080111610: 00 00 f9 f9 f9 f9 f9 f9 00 00 00 00 04 f9 f9 f9 0x000080111620: f9 f9 f9 f9 00 00 00 00 00 00 00 00 00 00 00 00 0x000080111630: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 0x000080111640: f9 f9 f9 f9 00 00 00 00 00 00 00 00 00 00 00 00 0x000080111650: 00 00 00 00 00 00 00 00 00 00 00 00 f9 f9 f9 f9 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 Left alloca redzone: ca Right alloca redzone: cb ==76344==ABORTING SHORT_READ

  1. invalid_access.jpeg

lepton v1.0-91619e2 START ACHIEVED 1468716389 229829

ASAN:DEADLYSIGNAL

==20540==ERROR: AddressSanitizer: SEGV on unknown address 0x0000008cec00 (pc 0x000000455164 bp 0x000000119d80 sp 0x7ffc54cfc1c0 T0)

0 0x455163 in setup_imginfo_jpg(bool) src/lepton/jpgcoder.cc:4023

#1 0x49649f in bool read_jpeg<ibytestream>(std::vector<std::pair<unsigned int, unsigned int>, std::allocator<std::pair<unsigned int, unsigned int> > >_, ibytestream_) src/lepton/jpgcoder.cc:2096
#2 0x446089 in std::function<bool ()>::operator()() const /usr/include/c++/6/functional:2136
#3 0x446089 in execute(std::function<bool ()> const&) src/lepton/jpgcoder.cc:1728
#4 0x46d8af in process_file(IOUtil::FileReader_, IOUtil::FileWriter_, int, bool) src/lepton/jpgcoder.cc:1510
#5 0x406c73 in main src/lepton/jpgcoder.cc:773
#6 0x7f816da5d82f in __libc_start_main (/lib/x86_64-linux-gnu/libc.so.6+0x2082f)
#7 0x40afc8 in _start (/home/marco/VulnResearch/misc/lepton/lepton+0x40afc8)

AddressSanitizer can not provide additional info. SUMMARY: AddressSanitizer: SEGV src/lepton/jpgcoder.cc:4023 in setup_imginfo_jpg(bool) ==20540==ABORTING SHORT_READ

  1. global_bof.jpeg

lepton v1.0-91619e2

START ACHIEVED 1468716464 964521

==45164==ERROR: AddressSanitizer: global-buffer-overflow on address 0x0000008c9f00 at pc 0x0000004571f1 bp 0x7ffeecdd5e30 sp 0x7ffeecdd5e20 READ of size 2 at 0x0000008c9f00 thread T0

0 0x4571f0 in setup_imginfo_jpg(bool) src/lepton/jpgcoder.cc:4023

#1 0x49649f in bool read_jpeg<ibytestream>(std::vector<std::pair<unsigned int, unsigned int>, std::allocator<std::pair<unsigned int, unsigned int> > >_, ibytestream_) src/lepton/jpgcoder.cc:2096
#2 0x446089 in std::function<bool ()>::operator()() const /usr/include/c++/6/functional:2136
#3 0x446089 in execute(std::function<bool ()> const&) src/lepton/jpgcoder.cc:1728
#4 0x46d8af in process_file(IOUtil::FileReader_, IOUtil::FileWriter_, int, bool) src/lepton/jpgcoder.cc:1510
#5 0x406c73 in main src/lepton/jpgcoder.cc:773
#6 0x7f16d425282f in __libc_start_main (/lib/x86_64-linux-gnu/libc.so.6+0x2082f)
#7 0x40afc8 in _start (/home/marco/VulnResearch/misc/lepton/lepton+0x40afc8)

0x0000008c9f00 is located 32 bytes to the left of global variable 'read_done' defined in 'src/lepton/jpgcoder.cc:302:9' (0x8c9f20) of size 8 0x0000008c9f00 is located 24 bytes to the right of global variable 'overall_start' defined in 'src/lepton/jpgcoder.cc:303:9' (0x8c9ee0) of size 8 SUMMARY: AddressSanitizer: global-buffer-overflow src/lepton/jpgcoder.cc:4023 in setup_imginfo_jpg(bool) Shadow bytes around the buggy address: 0x000080111390: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 0x0000801113a0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 0x0000801113b0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 0x0000801113c0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 0x0000801113d0: f9 f9 f9 f9 00 f9 f9 f9 f9 f9 f9 f9 00 f9 f9 f9 =>0x0000801113e0:[f9]f9 f9 f9 00 f9 f9 f9 f9 f9 f9 f9 00 f9 f9 f9 0x0000801113f0: f9 f9 f9 f9 00 f9 f9 f9 f9 f9 f9 f9 00 00 00 00 0x000080111400: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 0x000080111410: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 0x000080111420: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 0x000080111430: 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 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 Left alloca redzone: ca Right alloca redzone: cb ==45164==ABORTING SHORT_READ

  1. global_bof2.jpeg

lepton v1.0-91619e2

START ACHIEVED 1468716550 602819

==73428==ERROR: AddressSanitizer: global-buffer-overflow on address 0x0000008c7c28 at pc 0x00000045392d bp 0x7fff93915920 sp 0x7fff93915910 WRITE of size 2 at 0x0000008c7c28 thread T0

0 0x45392c in buildhuffcodes(unsigned char, unsigned char, huffCodes, huffTree_) src/lepton/jpgcoder.cc:5099

#1 0x45392c in parse_jfif_jpg(unsigned char, unsigned int, unsigned char_) src/lepton/jpgcoder.cc:4109
#2 0x46ffd0 in decode_jpeg(std::vector<std::pair<unsigned int, unsigned int>, std::allocator<std::pair<unsigned int, unsigned int> > > const&, std::vector<ThreadHandoff, std::allocator<ThreadHandoff> >_) src/lepton/jpgcoder.cc:2465
#3 0x446089 in std::function<bool ()>::operator()() const /usr/include/c++/6/functional:2136
#4 0x446089 in execute(std::function<bool ()> const&) src/lepton/jpgcoder.cc:1728
#5 0x46ccc8 in process_file(IOUtil::FileReader_, IOUtil::FileWriter_, int, bool) src/lepton/jpgcoder.cc:1525
#6 0x406c73 in main src/lepton/jpgcoder.cc:773
#7 0x7f8525d6782f in __libc_start_main (/lib/x86_64-linux-gnu/libc.so.6+0x2082f)
#8 0x40afc8 in _start (/home/marco/VulnResearch/misc/lepton/lepton+0x40afc8)

0x0000008c7c28 is located 24 bytes to the left of global variable 'hcodes' defined in 'src/lepton/jpgcoder.cc:311:16' (0x8c7c40) of size 8208 0x0000008c7c28 is located 8 bytes to the right of global variable 'htrees' defined in 'src/lepton/jpgcoder.cc:312:16' (0x8c5c20) of size 8192 SUMMARY: AddressSanitizer: global-buffer-overflow src/lepton/jpgcoder.cc:5099 in buildhuffcodes(unsigned char, unsigned char, huffCodes, huffTree_) Shadow bytes around the buggy address: 0x000080110f30: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 0x000080110f40: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 0x000080110f50: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 0x000080110f60: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 0x000080110f70: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 =>0x000080110f80: 00 00 00 00 f9[f9]f9 f9 00 00 00 00 00 00 00 00 0x000080110f90: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 0x000080110fa0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 0x000080110fb0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 0x000080110fc0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 0x000080110fd0: 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 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 Left alloca redzone: ca Right alloca redzone: cb ==73428==ABORTING SHORT_READ

  1. global_bof3.jpeg

lepton v1.0-91619e2

START ACHIEVED 1468716625 47000

==97386==ERROR: AddressSanitizer: global-buffer-overflow on address 0x0000008cad0a at pc 0x0000004fe249 bp 0x7fff934d51b0 sp 0x7fff934d51a0 READ of size 2 at 0x0000008cad0a thread T0

0 0x4fe248 in ProbabilityTablesBase::set_quantizationtable(BlockType, unsigned short const) src/vp8/model/model.hh:233

#1 0x4fe248 in VP8ComponentEncoder::vp8_full_encoder(UncompressedComponents const_, IOUtil::FileWriter_, ThreadHandoff const_, unsigned int) src/lepton/vp8_encoder.cc:465
#2 0x47b3a8 in write_ujpg(std::vector<ThreadHandoff, std::allocator<ThreadHandoff> >, std::vector<unsigned char, Sirikata::JpegAllocator<unsigned char> >_) src/lepton/jpgcoder.cc:3660
#3 0x48b4ee in bool std::_Bind<bool (_(std::vector<ThreadHandoff, std::allocator<ThreadHandoff> >, std::vector<unsigned char, Sirikata::JpegAllocator<unsigned char> >_))(std::vector<ThreadHandoff, std::allocator<ThreadHandoff> >, std::vector<unsigned char, Sirikata::JpegAllocator<unsigned char> >_)>::__call<bool, , 0ul, 1ul>(std::tuple<>&&, std::_Index_tuple<0ul, 1ul>) /usr/include/c++/6/functional:943
#4 0x48b4ee in bool std::_Bind<bool (*(std::vector<ThreadHandoff, std::allocator<ThreadHandoff> >, std::vector<unsigned char, Sirikata::JpegAllocator<unsigned char> >_))(std::vector<ThreadHandoff, std::allocator<ThreadHandoff> >, std::vector<unsigned char, Sirikata::JpegAllocator<unsigned char> >_)>::operator()<, bool>() /usr/include/c++/6/functional:1002
#5 0x48b4ee in std::_Function_handler<bool (), std::_Bind<bool (*(std::vector<ThreadHandoff, std::allocator<ThreadHandoff> >, std::vector<unsigned char, Sirikata::JpegAllocator<unsigned char> >_))(std::vector<ThreadHandoff, std::allocator<ThreadHandoff> >, std::vector<unsigned char, Sirikata::JpegAllocator<unsigned char> >_)> >::_M_invoke(std::_Any_data const&) /usr/include/c++/6/functional:1726
#6 0x446089 in std::function<bool ()>::operator()() const /usr/include/c++/6/functional:2136
#7 0x446089 in execute(std::function<bool ()> const&) src/lepton/jpgcoder.cc:1728
#8 0x46ceb5 in process_file(IOUtil::FileReader_, IOUtil::FileWriter_, int, bool) src/lepton/jpgcoder.cc:1531
#9 0x406c73 in main src/lepton/jpgcoder.cc:773
#10 0x7fe3fb5cd82f in __libc_start_main (/lib/x86_64-linux-gnu/libc.so.6+0x2082f)
#11 0x40afc8 in _start (/home/marco/VulnResearch/misc/lepton/lepton+0x40afc8)

0x0000008cad0a is located 54 bytes to the left of global variable 'chroma_debug_height' defined in 'src/vp8/util/debug.cc:23:5' (0x8cad40) of size 4 0x0000008cad0a is located 6 bytes to the right of global variable 'raw_decoded_fp_Y' defined in 'src/vp8/util/debug.cc:109:5' (0x8cad00) of size 4 SUMMARY: AddressSanitizer: global-buffer-overflow src/vp8/model/model.hh:233 in ProbabilityTablesBase::set_quantization_table(BlockType, unsigned short const*) Shadow bytes around the buggy address: 0x000080111550: f9 f9 f9 f9 00 f9 f9 f9 f9 f9 f9 f9 00 f9 f9 f9 0x000080111560: f9 f9 f9 f9 00 00 00 00 00 00 00 00 00 f9 f9 f9 0x000080111570: f9 f9 f9 f9 00 00 00 00 00 00 00 00 00 00 00 00 0x000080111580: 00 00 00 00 00 00 00 00 00 00 00 00 f9 f9 f9 f9 0x000080111590: 04 f9 f9 f9 f9 f9 f9 f9 04 f9 f9 f9 f9 f9 f9 f9 =>0x0000801115a0: 04[f9]f9 f9 f9 f9 f9 f9 04 f9 f9 f9 f9 f9 f9 f9 0x0000801115b0: 04 f9 f9 f9 f9 f9 f9 f9 04 f9 f9 f9 f9 f9 f9 f9 0x0000801115c0: 04 f9 f9 f9 f9 f9 f9 f9 04 f9 f9 f9 f9 f9 f9 f9 0x0000801115d0: 04 f9 f9 f9 f9 f9 f9 f9 04 f9 f9 f9 f9 f9 f9 f9 0x0000801115e0: 04 f9 f9 f9 f9 f9 f9 f9 04 f9 f9 f9 f9 f9 f9 f9 0x0000801115f0: 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 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 Left alloca redzone: ca Right alloca redzone: cb ==97386==ABORTING SHORT_READ

Thank you

Marco

danielrh commented 8 years ago

Hmm I think my blanket bounds checks caught some of them. changed them to report the actual problem.

danielrh commented 8 years ago

All the files get rejected early now and the quantization tables are properly bounded, and all global accesses are bounds checked, so marking this closed Thanks for the report!

If you continue to notice problems, please reopen.

czchen commented 8 years ago

@danielrh

Is version 1.2.1 fixed these CVE? I am working on fixing lepton in Debian so I need to know if 1.2.1 is good for it.