LIEF icon indicating copy to clipboard operation
LIEF copied to clipboard

SEGV in LIEF::DEX::Method::set_virtual at DEX/Method.cpp:84

Open bladchan opened this issue 1 year ago • 0 comments

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

Poc here : vdex_segv_1.zip

To Reproduce

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

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

	return 0;
}
  1. Run Poc:
$ ./read_vdex ./vdex_segv_1.bin

Expected behavior Parse the VDEX 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 : VDEX
  • LIEF commit version: https://github.com/lief-project/LIEF/commit/ad811916670e83947560b6f3c45df6e71d3885af

Additional context ASAN says:

$ ./read_vdex vdex_segv_1.bin
Different values for string offset between map and header
Different values for string size between map and header
...
method->index() is not consistent
method->index() is not consistent
AddressSanitizer:DEADLYSIGNAL
=================================================================
==30568==ERROR: AddressSanitizer: SEGV on unknown address 0x000000000000 (pc 0x5563a831ff1c bp 0x0fffa2253c5c sp 0x7ffd1129e290 T0)
==30568==The signal is caused by a READ memory access.
==30568==Hint: address points to the zero page.
    #0 0x5563a831ff1b in LIEF::DEX::Method::set_virtual(bool) /home/ubuntu/test/LIEF/src/DEX/Method.cpp:84
    #1 0x5563a8282c69 in void LIEF::DEX::Parser::parse_method<LIEF::DEX::details::DEX37>(unsigned long, LIEF::DEX::Class&, bool) /home/ubuntu/test/LIEF/src/DEX/Parser.tcc:620
    #2 0x5563a826ec95 in void LIEF::DEX::Parser::parse_class_data<LIEF::DEX::details::DEX37>(unsigned int, LIEF::DEX::Class&) /home/ubuntu/test/LIEF/src/DEX/Parser.tcc:551
    #3 0x5563a824d995 in void LIEF::DEX::Parser::parse_classes<LIEF::DEX::details::DEX37>() /home/ubuntu/test/LIEF/src/DEX/Parser.tcc:463
    #4 0x5563a8238421 in void LIEF::DEX::Parser::parse_file<LIEF::DEX::details::DEX37>() /home/ubuntu/test/LIEF/src/DEX/Parser.tcc:45
    #5 0x5563a8233e80 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:82
    #6 0x5563a823356d in LIEF::DEX::Parser::parse(std::vector<unsigned char, std::allocator<unsigned char> >, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&) /home/ubuntu/test/LIEF/src/DEX/Parser.cpp:52
    #7 0x5563a7eadf9d in void LIEF::VDEX::Parser::parse_dex_files<LIEF::VDEX::details::VDEX10>() /home/ubuntu/test/LIEF/src/VDEX/Parser.tcc:89
    #8 0x5563a7ea3ebb in void LIEF::VDEX::Parser::parse_file<LIEF::VDEX::details::VDEX10>() (/home/ubuntu/test/LIEF/fuzz/read_vdex+0x4d5ebb)
    #9 0x5563a7e99b28 in LIEF::VDEX::Parser::init(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, unsigned int) /home/ubuntu/test/LIEF/src/VDEX/Parser.cpp:87
    #10 0x5563a7e9978a in LIEF::VDEX::Parser::Parser(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&) /home/ubuntu/test/LIEF/src/VDEX/Parser.cpp:75
    #11 0x5563a7e98ab1 in LIEF::VDEX::Parser::parse(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&) /home/ubuntu/test/LIEF/src/VDEX/Parser.cpp:35
    #12 0x5563a7cfe856 in main /home/ubuntu/test/LIEF/fuzz/read_vdex.c:10
    #13 0x7fa9ca5c8082 in __libc_start_main ../csu/libc-start.c:308
    #14 0x5563a7cfe55d in _start (/home/ubuntu/test/LIEF/fuzz/read_vdex+0x33055d)

AddressSanitizer can not provide additional info.
SUMMARY: AddressSanitizer: SEGV /home/ubuntu/test/LIEF/src/DEX/Method.cpp:84 in LIEF::DEX::Method::set_virtual(bool)
==30568==ABORTING

bladchan avatar Sep 16 '22 15:09 bladchan