Headline
CVE-2021-20285: canPack@p_lx_elf.cpp:2571 BufferOverflow (both latest release version and devel version) · Issue #421 · upx/upx
A flaw was found in upx canPack in p_lx_elf.cpp in UPX 3.96. This flaw allows attackers to cause a denial of service (SEGV or buffer overflow and application crash) or possibly have unspecified other impacts via a crafted ELF. The highest threat from this vulnerability is to system availability.
What’s the problem (or question)?
An issue was discovered in upx 3.96(devel branch), There is an illegal memory access in function canPack at p_lx_elf.cpp:2571.
I also check the newest release version meet the same crash, lies at p_lx_elf.cpp:2490.
What should have happened?
no illegal memory access (crash)
Do you have an idea for a solution?
check the relocation_offset and do not access the illegal memory
How can we reproduce the issue?
- Compile the devel branch with sanitize open
export BUILD_TYPE_SANITIZE=1; make all - Use upx.out poc and get crash
download the poc here.
source
2566 unsigned rel_off = get_te64(&dynseg[-1+ z_rel].d_val); 2567 Elf64_Rela *rp = (Elf64_Rela *)&file_image[rel_off]; 2568 unsigned relsz = get_te64(&dynseg[-1+ z_rsz].d_val); 2569 Elf64_Rela *last = (Elf64_Rela *)(relsz + (char *)rp); 2570 for (; rp < last; ++rp) { 2571 unsigned r_va = get_te64(&rp->r_offset); 2572 if (r_va == user_init_ava) { // found the Elf64_Rela 2573 unsigned r_info = get_te64(&rp->r_info); 2574 unsigned r_type = ELF64_R_TYPE(r_info); 2575 if (Elf64_Ehdr::EM_AARCH64 == e_machine 2576 && R_AARCH64_RELATIVE == r_type) { 2577 user_init_va = get_te64(&rp->r_addend); 2578 }
the source code didn’t check the rel_off so get an illegal rp
debug
bug report
ASAN:SIGSEGV
==65507==ERROR: AddressSanitizer: SEGV on unknown address 0x6300004013e8 (pc 0x00000055aff0 bp 0x0c3600003e31 sp 0x7ffc8f9b7378 T0) #0 0x55afef in get_le64(void const*) /home/wanghao/upx_dev/src/bele_policy.h:193 #1 0x55afef in N_BELE_RTP::LEPolicy::get64(void const*) const /home/wanghao/upx_dev/src/bele_policy.h:194 #2 0x49dfe2 in Packer::get_te64(void const*) const /home/wanghao/upx_dev/src/packer.h:297 #3 0x49dfe2 in PackLinuxElf64::canPack() /home/wanghao/upx_dev/src/p_lx_elf.cpp:2571 #4 0x5240a6 in try_pack /home/wanghao/upx_dev/src/packmast.cpp:91 #5 0x52518f in PackMaster::visitAllPackers(Packer* (*)(Packer*, void*), InputFile*, options_t const*, void*) /home/wanghao/upx_dev/src/packmast.cpp:194 #6 0x526d19 in PackMaster::getPacker(InputFile*) /home/wanghao/upx_dev/src/packmast.cpp:240 #7 0x526e3c in PackMaster::pack(OutputFile*) /home/wanghao/upx_dev/src/packmast.cpp:260 #8 0x55bede in do_one_file(char const*, char*) /home/wanghao/upx_dev/src/work.cpp:158 #9 0x55c3ae in do_files(int, int, char**) /home/wanghao/upx_dev/src/work.cpp:271 #10 0x403dbe in main /home/wanghao/upx_dev/src/main.cpp:1538 #11 0x7f702527783f in __libc_start_main (/lib/x86_64-linux-gnu/libc.so.6+0x2083f)
Please tell us details about your environment.
- UPX version used (both upx 3.96(devel) and upx 3.96 release):
- Host Operating System and version: ubuntu 16.04
- Host CPU architecture: Intel® Core™ i7-9750H CPU @ 2.60GHz
- Target Operating System and version: ubuntu 16.04
- Target CPU architecture: Intel® Core™ i7-9750H CPU @ 2.60GHz