LIEF icon indicating copy to clipboard operation
LIEF copied to clipboard

SEGV in LIEF::DEX::Type::parse at DEX/Type.cpp:107

Open bladchan opened this issue 1 year ago • 0 comments

Describe the bug A bad DEX file which can lead LIEF::DEX::Parser::parse()/LIEF::VDEX::Parser::parse() to segmentation fault.

Poc here : dex_segv_3.zip

To Reproduce

  1. Build the whole project with ASAN
  2. Drive programs (compile it with ASAN too):
// read_dex.c
#include <LIEF/LIEF.hpp>

int main(int argc, char** argv){
	
	if(argc != 2) return 0;
	
	// DEX
	try {
	    std::unique_ptr<LIEF::DEX::File> dex = LIEF::DEX::Parser::parse(argv[1]);
	    if(dex) std::cout << *dex << std::endl;
	} catch (const LIEF::exception& err) {
	    std::cerr << err.what() << std::endl;
	}

	return 0;
}
  1. Run Poc:
$ ./read_dex ./dex_segv_3.bin

Expected behavior Parse the DEX file without segmentation fault because segmentation fault can cause a Denial of Service (Dos).

Environment (please complete the following information):

  • System and Version : Ubuntu 20.04 + gcc 9.4.0
  • Target format : DEX
  • LIEF commit version: https://github.com/lief-project/LIEF/commit/ad811916670e83947560b6f3c45df6e71d3885af

Additional context ASAN says:

$ ./read_dex dex_segv_3.bin 
Different values for string offset between map and header
Different values for string size between map and header
Unknown type: ''
Unknown type: ''
Unknown type: ''
Unknown type: ''
Unknown type: ''
Unknown type: ''
Unknown type: ''
Unknown type: ''
AddressSanitizer:DEADLYSIGNAL
=================================================================
==34053==ERROR: AddressSanitizer: SEGV on unknown address 0x000000000000 (pc 0x7fcb74be99c4 bp 0x7ffe99a34e00 sp 0x7ffe99a34d68 T0)
==34053==The signal is caused by a READ memory access.
==34053==Hint: address points to the zero page.
    #0 0x7fcb74be99c3 in std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >::operator[](unsigned long) const (/lib/x86_64-linux-gnu/libstdc++.so.6+0x1439c3)
    #1 0x564285930f3e in LIEF::DEX::Type::parse(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&) /home/ubuntu/test/LIEF/src/DEX/Type.cpp:107
    #2 0x56428593028a in LIEF::DEX::Type::Type(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&) /home/ubuntu/test/LIEF/src/DEX/Type.cpp:27
    #3 0x5642858052a1 in std::_MakeUniq<LIEF::DEX::Type>::__single_object std::make_unique<LIEF::DEX::Type, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >&>(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >&) /usr/include/c++/9/bits/unique_ptr.h:857
    #4 0x5642857d6b59 in void LIEF::DEX::Parser::parse_types<LIEF::DEX::details::DEX35>() /home/ubuntu/test/LIEF/src/DEX/Parser.tcc:158
    #5 0x5642857ce7ad in void LIEF::DEX::Parser::parse_file<LIEF::DEX::details::DEX35>() /home/ubuntu/test/LIEF/src/DEX/Parser.tcc:41
    #6 0x5642857c4dad in LIEF::DEX::Parser::init(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, unsigned int) /home/ubuntu/test/LIEF/src/DEX/Parser.cpp:78
    #7 0x5642857c4197 in LIEF::DEX::Parser::parse(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&) /home/ubuntu/test/LIEF/src/DEX/Parser.cpp:40
    #8 0x56428562d856 in main /home/ubuntu/test/LIEF/fuzz/read_dex.c:9
    #9 0x7fcb7476e082 in __libc_start_main ../csu/libc-start.c:308
    #10 0x56428562d55d in _start (/home/ubuntu/test/LIEF/fuzz/read_dex+0x33055d)

AddressSanitizer can not provide additional info.
SUMMARY: AddressSanitizer: SEGV (/lib/x86_64-linux-gnu/libstdc++.so.6+0x1439c3) in std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >::operator[](unsigned long) const
==34053==ABORTING

bladchan avatar Sep 17 '22 01:09 bladchan