A heap-based buffer overflow was discovered in upx, during the variable 'bucket' points to an inaccessible address. The issue is being triggered in the function PackLinuxElf64::invert_pt_dynamic at p_lx_elf.cpp:5239.
ASAN reports:
==110294==ERROR: AddressSanitizer: heap-buffer-overflow on address 0x63000000f760 at pc 0x000000466f38 bp 0x7ffcebb0b6a0 sp 0x7ffcebb0b690
READ of size 4 at 0x63000000f760 thread T0
#0 0x466f37 in PackLinuxElf64::invert_pt_dynamic(N_Elf::Dyn<N_Elf::ElfITypes<LE16, LE32, LE64, LE64, LE64> > const*) /home/test/Desktop/EVAULATION/upx/src/p_lx_elf.cpp:5239#1 0x46f660 in PackLinuxElf64::invert_pt_dynamic(N_Elf::Dyn<N_Elf::ElfITypes<LE16, LE32, LE64, LE64, LE64> > const*) /home/test/Desktop/EVAULATION/upx/src/p_lx_elf.cpp:5127#2 0x46f660 in PackLinuxElf64::PackLinuxElf64help1(InputFile*) /home/test/Desktop/EVAULATION/upx/src/p_lx_elf.cpp:795#3 0x470479 in PackLinuxElf64Le::PackLinuxElf64Le(InputFile*) /home/test/Desktop/EVAULATION/upx/src/p_lx_elf.h:407#4 0x470479 in PackLinuxElf64amd::PackLinuxElf64amd(InputFile*) /home/test/Desktop/EVAULATION/upx/src/p_lx_elf.cpp:1008#5 0x4f34b2 in PackMaster::visitAllPackers(Packer* (*)(Packer*, void*), InputFile*, options_t const*, void*) /home/test/Desktop/EVAULATION/upx/src/packmast.cpp:194#6 0x4f50f9 in PackMaster::getUnpacker(InputFile*) /home/test/Desktop/EVAULATION/upx/src/packmast.cpp:248#7 0x4f521f in PackMaster::unpack(OutputFile*) /home/test/Desktop/EVAULATION/upx/src/packmast.cpp:266#8 0x52a1e6 in do_one_file(char const*, char*) /home/test/Desktop/EVAULATION/upx/src/work.cpp:160#9 0x52a69e in do_files(int, int, char**) /home/test/Desktop/EVAULATION/upx/src/work.cpp:271#10 0x403ace in main /home/test/Desktop/EVAULATION/upx/src/main.cpp:1538#11 0x7f8a7e1c882f in __libc_start_main (/lib/x86_64-linux-gnu/libc.so.6+0x2082f)#12 0x404828 in _start (/home/test/Desktop/EVAULATION/upx/src/upx.out+0x404828)
0x63000000f760 is located 0 bytes to the right of 62304-byte region [0x630000000400,0x63000000f760)
allocated by thread T0 here:
#0 0x7f8a7edbc602 in malloc (/usr/lib/x86_64-linux-gnu/libasan.so.2+0x98602)#1 0x42732a in MemBuffer::alloc(unsigned long long) /home/test/Desktop/EVAULATION/upx/src/mem.cpp:194
SUMMARY: AddressSanitizer: heap-buffer-overflow /home/test/Desktop/EVAULATION/upx/src/p_lx_elf.cpp:5239 PackLinuxElf64::invert_pt_dynamic(N_Elf::Dyn<N_Elf::ElfITypes<LE16, LE32, LE64, LE64, LE64>> const*)
Shadow bytes around the buggy address:
0x0c607fff9e90: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
0x0c607fff9ea0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
0x0c607fff9eb0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
0x0c607fff9ec0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
0x0c607fff9ed0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
=>0x0c607fff9ee0: 00 00 00 00 00 00 00 00 00 00 00 00[fa]fa fa fa
0x0c607fff9ef0: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
0x0c607fff9f00: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
0x0c607fff9f10: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
0x0c607fff9f20: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
0x0c607fff9f30: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
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
==110294==ABORTING
What's the problem (or question)?
A heap-based buffer overflow was discovered in upx, during the variable 'bucket' points to an inaccessible address. The issue is being triggered in the function PackLinuxElf64::invert_pt_dynamic at p_lx_elf.cpp:5239.
ASAN reports:
==110294==ERROR: AddressSanitizer: heap-buffer-overflow on address 0x63000000f760 at pc 0x000000466f38 bp 0x7ffcebb0b6a0 sp 0x7ffcebb0b690 READ of size 4 at 0x63000000f760 thread T0 #0 0x466f37 in PackLinuxElf64::invert_pt_dynamic(N_Elf::Dyn<N_Elf::ElfITypes<LE16, LE32, LE64, LE64, LE64> > const*) /home/test/Desktop/EVAULATION/upx/src/p_lx_elf.cpp:5239 #1 0x46f660 in PackLinuxElf64::invert_pt_dynamic(N_Elf::Dyn<N_Elf::ElfITypes<LE16, LE32, LE64, LE64, LE64> > const*) /home/test/Desktop/EVAULATION/upx/src/p_lx_elf.cpp:5127 #2 0x46f660 in PackLinuxElf64::PackLinuxElf64help1(InputFile*) /home/test/Desktop/EVAULATION/upx/src/p_lx_elf.cpp:795 #3 0x470479 in PackLinuxElf64Le::PackLinuxElf64Le(InputFile*) /home/test/Desktop/EVAULATION/upx/src/p_lx_elf.h:407 #4 0x470479 in PackLinuxElf64amd::PackLinuxElf64amd(InputFile*) /home/test/Desktop/EVAULATION/upx/src/p_lx_elf.cpp:1008 #5 0x4f34b2 in PackMaster::visitAllPackers(Packer* (*)(Packer*, void*), InputFile*, options_t const*, void*) /home/test/Desktop/EVAULATION/upx/src/packmast.cpp:194 #6 0x4f50f9 in PackMaster::getUnpacker(InputFile*) /home/test/Desktop/EVAULATION/upx/src/packmast.cpp:248 #7 0x4f521f in PackMaster::unpack(OutputFile*) /home/test/Desktop/EVAULATION/upx/src/packmast.cpp:266 #8 0x52a1e6 in do_one_file(char const*, char*) /home/test/Desktop/EVAULATION/upx/src/work.cpp:160 #9 0x52a69e in do_files(int, int, char**) /home/test/Desktop/EVAULATION/upx/src/work.cpp:271 #10 0x403ace in main /home/test/Desktop/EVAULATION/upx/src/main.cpp:1538 #11 0x7f8a7e1c882f in __libc_start_main (/lib/x86_64-linux-gnu/libc.so.6+0x2082f) #12 0x404828 in _start (/home/test/Desktop/EVAULATION/upx/src/upx.out+0x404828) 0x63000000f760 is located 0 bytes to the right of 62304-byte region [0x630000000400,0x63000000f760) allocated by thread T0 here: #0 0x7f8a7edbc602 in malloc (/usr/lib/x86_64-linux-gnu/libasan.so.2+0x98602) #1 0x42732a in MemBuffer::alloc(unsigned long long) /home/test/Desktop/EVAULATION/upx/src/mem.cpp:194 SUMMARY: AddressSanitizer: heap-buffer-overflow /home/test/Desktop/EVAULATION/upx/src/p_lx_elf.cpp:5239 PackLinuxElf64::invert_pt_dynamic(N_Elf::Dyn<N_Elf::ElfITypes<LE16, LE32, LE64, LE64, LE64> > const*) Shadow bytes around the buggy address: 0x0c607fff9e90: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 0x0c607fff9ea0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 0x0c607fff9eb0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 0x0c607fff9ec0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 0x0c607fff9ed0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 =>0x0c607fff9ee0: 00 00 00 00 00 00 00 00 00 00 00 00[fa]fa fa fa 0x0c607fff9ef0: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa 0x0c607fff9f00: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa 0x0c607fff9f10: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa 0x0c607fff9f20: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa 0x0c607fff9f30: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa 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 ==110294==ABORTINGThen analysis the reasons for segv by debugging:
The instruction to crash is, corresponds to the bucket [j] in the source code
mov eax, DWORD PTR [rdi+rsi*4+0x14]The register rdi and rsi are:
The DWORD PTR pointer to 0xa20000, where is a invalid address.
What should have happened?
Decompress a crafted/suspicious file.
Do you have an idea for a solution?
A boundary check is needed for loop variable 'j' because the size allocated for variable 'buckets' is limited.
How can we reproduce the issue?
upx.out -df $PoC -o /dev/nullPoc can be found here.
Please tell us details about your environment.
upx --version):Ubuntu 16.04 64-bit
Intel(R) Core(TM) i5-6200U CPU @ 2.30GHz with 8GB
same as Host
same as Host
The text was updated successfully, but these errors were encountered: