DIPlib / diplib

Quantitative Image Analysis in C++, MATLAB and Python
https://diplib.org
Apache License 2.0
228 stars 50 forks source link

Double-Free of ImageReadJPEG #80

Closed NigelX closed 3 years ago

NigelX commented 3 years ago

Hi

I found an crash erro.

System info: Ubuntu 20.04 : clang 10.0.0 , gcc 9.3.0

DIPliB Release v3.0.0

commit:7db848500f4cc5db676b32e9a95dcbc94d976339

[poc1.zip](https://github.com/DIPlib/diplib/files/6966666/poc1.zip) (edit: careful with this, looks malicious)


Verification steps: 1.Get the source code of DIPliB 2.Compile the DIPliB and poc.cc

$ cd diplib
$ mkdir build && cd build
$ cmake ../ -DCMAKE_C_COMPILER=clang -DCMAKE_CXX_COMPILER=clang++ -DCMAKE_C_FLAGS="-O2 -fno-omit-frame-pointer -g -fsanitize=address" -DCMAKE_CXX_FLAGS="-O2 -fno-omit-frame-pointer -g -fsanitize=address"
$ make -j 32
$ sudo make install
$ cp src/libDIP.so ./
$ clang++ -g poc.cc -O2 -fno-omit-frame-pointer -fsanitize=address  -fsanitize-coverage=bb -I/usr/local/include -lDIP -L. -Wl,-rpath,. -o poc

3.run poc

$ ./poc crash.jpg

asan info

=================================================================
==2969722==ERROR: AddressSanitizer: attempting double-free on 0x60b0000001a0 in thread T0:
    #0 0x4c5ccd in operator delete(void*) (/home/topsec/Downloads/diplib/build/poc+0x4c5ccd)
    #1 0x7f036377cf05 in dip::ImageReadJPEG(dip::Image&, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&) /usr/bin/../lib/gcc/x86_64-linux-gnu/9/../../../../include/c++/9/bits/basic_string.h
    #2 0x4c870c in dip::ImageReadJPEG(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&) /usr/local/include/diplib/file_io.h:356:4
    #3 0x4c870c in main /home/topsec/Downloads/diplib/build/poc.cc:20:19
    #4 0x7f03623c60b2 in __libc_start_main /build/glibc-eX1tMB/glibc-2.31/csu/../csu/libc-start.c:308:16
    #5 0x41d5bd in _start (/home/topsec/Downloads/diplib/build/poc+0x41d5bd)

0x60b0000001a0 is located 0 bytes inside of 99-byte region [0x60b0000001a0,0x60b000000203)
freed by thread T0 here:
    #0 0x4c5ccd in operator delete(void*) (/home/topsec/Downloads/diplib/build/poc+0x4c5ccd)
    #1 0x7f036377f4e5 in __gnu_cxx::new_allocator<char>::deallocate(char*, unsigned long) /usr/bin/../lib/gcc/x86_64-linux-gnu/9/../../../../include/c++/9/ext/new_allocator.h:128:2
    #2 0x7f036377f4e5 in std::allocator_traits<std::allocator<char> >::deallocate(std::allocator<char>&, char*, unsigned long) /usr/bin/../lib/gcc/x86_64-linux-gnu/9/../../../../include/c++/9/bits/alloc_traits.h:470:13
    #3 0x7f036377f4e5 in std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >::_M_destroy(unsigned long) /usr/bin/../lib/gcc/x86_64-linux-gnu/9/../../../../include/c++/9/bits/basic_string.h:237:9
    #4 0x7f036377f4e5 in std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >::_M_dispose() /usr/bin/../lib/gcc/x86_64-linux-gnu/9/../../../../include/c++/9/bits/basic_string.h:232:4
    #5 0x7f036377f4e5 in std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >::~basic_string() /usr/bin/../lib/gcc/x86_64-linux-gnu/9/../../../../include/c++/9/bits/basic_string.h:658:9
    #6 0x7f036377f4e5 in dip::(anonymous namespace)::JpegInput::JpegInput(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >) /home/topsec/Downloads/diplib/src/file_io/jpeg.cpp:77:7
    #7 0x7f036377bed2 in dip::ImageReadJPEG(dip::Image&, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&) /home/topsec/Downloads/diplib/src/file_io/jpeg.cpp:194:4
    #8 0x4c870c in dip::ImageReadJPEG(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&) /usr/local/include/diplib/file_io.h:356:4
    #9 0x4c870c in main /home/topsec/Downloads/diplib/build/poc.cc:20:19
    #10 0x7f03623c60b2 in __libc_start_main /build/glibc-eX1tMB/glibc-2.31/csu/../csu/libc-start.c:308:16

previously allocated by thread T0 here:
    #0 0x4c546d in operator new(unsigned long) (/home/topsec/Downloads/diplib/build/poc+0x4c546d)
    #1 0x7f036377b4a6 in void std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >::_M_construct<char*>(char*, char*, std::forward_iterator_tag) /usr/bin/../lib/gcc/x86_64-linux-gnu/9/../../../../include/c++/9/bits/basic_string.tcc:219:14
    #2 0x7f036377b4a6 in void std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >::_M_construct_aux<char*>(char*, char*, std::__false_type) /usr/bin/../lib/gcc/x86_64-linux-gnu/9/../../../../include/c++/9/bits/basic_string.h:247:11
    #3 0x7f036377b4a6 in void std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >::_M_construct<char*>(char*, char*) /usr/bin/../lib/gcc/x86_64-linux-gnu/9/../../../../include/c++/9/bits/basic_string.h:266:4
    #4 0x7f036377b4a6 in std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >::basic_string(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&) /usr/bin/../lib/gcc/x86_64-linux-gnu/9/../../../../include/c++/9/bits/basic_string.h:451:9
    #5 0x7f036377b4a6 in dip::ImageReadJPEG(dip::Image&, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&) /home/topsec/Downloads/diplib/src/file_io/jpeg.cpp:181:20
    #6 0x4c870c in dip::ImageReadJPEG(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&) /usr/local/include/diplib/file_io.h:356:4
    #7 0x4c870c in main /home/topsec/Downloads/diplib/build/poc.cc:20:19
    #8 0x7f03623c60b2 in __libc_start_main /build/glibc-eX1tMB/glibc-2.31/csu/../csu/libc-start.c:308:16

SUMMARY: AddressSanitizer: double-free (/home/topsec/Downloads/diplib/build/poc+0x4c5ccd) in operator delete(void*)
==2969722==ABORTING

Thank you, Product Security

NigelX commented 3 years ago

https://cwe.mitre.org/data/definitions/415.html