LIEF icon indicating copy to clipboard operation
LIEF copied to clipboard

Allocation-size-too-big in LIEF::DEX::Method

Open bladchan opened this issue 1 year ago • 1 comments

Describe the bug A bad DEX file may lead the LIEF::DEX::parse() to new a large size LIEF::DEX::Method* object which absolutely allocation failed. This may cause SEGV in the future.

Poc here: dex_alloc_size_too_big.zip

To Reproduce Build the whole project with ASAN Drive program (compile it with ASAN too):

  1. Build the whole project with ASAN
  2. Drive program (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_alloc_size_too_big.bin

Expected behavior It seems that some fields in DEX file decides the total number of LIEF::DEX::Method. A bad number will lead the parser to allocate a large size area. Maybe setting a MAX_SIZE for LIEF::DEX::Method[] will alleviate this issue?

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_alloc_size_too_big.bin
Unknown type: ''
Unknown type: 'a'
Unknown type: 'a'
Unknown type: 't'
Unknown type: '0'
Unknown type: 'o'
Unknown type: ''
Unknown type: ''
Unknown type: 'v'
Unknown type: 'A'
Unknown type: ''
Unknown type: ''
Unknown type: ' '
Unknown type: 'a'
Unknown type: 'n'
Unknown type: '5'
Unknown type: ''
Unknown type: ''
Empty field name
Name of method #0 is out of bound!
Empty class name
Empty class name
Empty class name
Empty class name
Empty class name
Empty class name
Empty class name
Empty class name
Empty class name
Corrupted field index #10 for class:  (7 fields)
method->index() is not consistent
Corrupted method index #32 for class:  (5 methods)
Corrupted field index #10 for class:  (7 fields)
Corrupted field index #137438953347 for class:   (7 fields)
method->index() is not consistent
method->index() is not consistent
Corrupted field index #137438953347 for class: aiout (7 fields)
=================================================================
==34655==ERROR: AddressSanitizer: requested allocation size 0xfffffffc20 (0x10000000c20 after adjustments for alignment, red zones etc.) exceeds maximum supported size of 0x10000000000 (thread T0)
    #0 0x7fb6ce3c4587 in operator new(unsigned long) ../../../../src/libsanitizer/asan/asan_new_delete.cc:104
    #1 0x5576538d4d86 in __gnu_cxx::new_allocator<LIEF::DEX::Method*>::allocate(unsigned long, void const*) /usr/include/c++/9/ext/new_allocator.h:114

==34655==HINT: if you don't care about these errors you may set allocator_may_return_null=1
SUMMARY: AddressSanitizer: allocation-size-too-big ../../../../src/libsanitizer/asan/asan_new_delete.cc:104 in operator new(unsigned long)
==34655==ABORTING

bladchan avatar Sep 17 '22 02:09 bladchan

Thank you again @bladchan for reporting these issues. I'll try to process them in the next two weeks

romainthomas avatar Sep 20 '22 03:09 romainthomas

Thank you @bladchan for all these issues. It is fixed now.

romainthomas avatar Sep 23 '22 06:09 romainthomas