Project: upx (upx/upx), language: c++
Vulnerability instance: upx.cve-2021-43316
Sanitizer: address

================= Bug Report (1/1) ==================
## Source: GitHub Issue
## URL: https://github.com/upx/upx/issues/381
## Description:
Issue: upx/upx#381
Title: [bug] segv fault in get_le64()
State: closed
Created by: 14isnot40
Created at: 2020-05-23 14:28:34+00:00

Issue Body:
## What's the problem (or question)?
A heap-based buffer overflow was discovered in upx, during the genric pointer 'p' points to an inaccessible address in func get_le64(). The issue can cause a denial of service. The issue is diff from [issue367](https://github.com/upx/upx/issues/367) and [issue368](https://github.com/upx/upx/issues/368)

ASAN reports:
```bash
ASAN:SIGSEGV
=================================================================
==113201==ERROR: AddressSanitizer: SEGV on unknown address 0x630011d04b20 (pc 0x0000005292e0 bp 0x000000000022 sp 0x7ffebc640bc8 T0)
    #0 0x5292df in get_le64(void const*) /home/test/Desktop/EVAULATION/upx/src/bele_policy.h:193
    #1 0x5292df in N_BELE_RTP::LEPolicy::get64(void const*) const /home/test/Desktop/EVAULATION/upx/src/bele_policy.h:194
    #2 0x45784b in Packer::get_te64(void const*) const /home/test/Desktop/EVAULATION/upx/src/packer.h:297
    #3 0x45784b in PackLinuxElf64::elf_lookup(char const*) const /home/test/Desktop/EVAULATION/upx/src/p_lx_elf.cpp:5423
    #4 0x46f7eb in PackLinuxElf64::PackLinuxElf64help1(InputFile*) /home/test/Desktop/EVAULATION/upx/src/p_lx_elf.cpp:805
    #5 0x470479 in PackLinuxElf64Le::PackLinuxElf64Le(InputFile*) /home/test/Desktop/EVAULATION/upx/src/p_lx_elf.h:407
    #6 0x470479 in PackLinuxElf64amd::PackLinuxElf64amd(InputFile*) /home/test/Desktop/EVAULATION/upx/src/p_lx_elf.cpp:1008
    #7 0x4f34b2 in PackMaster::visitAllPackers(Packer* (*)(Packer*, void*), InputFile*, options_t const*, void*) /home/test/Desktop/EVAULATION/upx/src/packmast.cpp:194
    #8 0x4f50f9 in PackMaster::getUnpacker(InputFile*) /home/test/Desktop/EVAULATION/upx/src/packmast.cpp:248
    #9 0x4f521f in PackMaster::unpack(OutputFile*) /home/test/Desktop/EVAULATION/upx/src/packmast.cpp:266
    #10 0x52a1e6 in do_one_file(char const*, char*) /home/test/Desktop/EVAULATION/upx/src/work.cpp:160
    #11 0x52a69e in do_files(int, int, char**) /home/test/Desktop/EVAULATION/upx/src/work.cpp:271
    #12 0x403ace in main /home/test/Desktop/EVAULATION/upx/src/main.cpp:1538
    #13 0x7fc4129b682f in __libc_start_main (/lib/x86_64-linux-gnu/libc.so.6+0x2082f)
    #14 0x404828 in _start (/home/test/Desktop/EVAULATION/upx/src/upx.out+0x404828)

AddressSanitizer can not provide additional info.
SUMMARY: AddressSanitizer: SEGV /home/test/Desktop/EVAULATION/upx/src/bele_policy.h:193 get_le64(void const*)
==113201==ABORTING
```
The essential cause of the bug is at PackLinuxElf64 :: elf_lookup () at p_lx_elf: 5423:
```cpp
upx_uint64_t const w = get_te64(&bitmask[(n_bitmask -1) & (h>>6)]);
```


## What should have happened?
Decompress a crafted/suspicious file.

## Do you have an idea for a solution?
We are very grateful to @jreiser for patching the bucket in p_lx_elf.cpp in the [issue 367](https://github.com/upx/upx/issues/365). However, in fact, all places involving get_te64 () should be strengthened in upx, especially in p_lx_elf.cpp. The position we reported should be patched at least:
position in PackLinuxElf64::elf_lookup() at p_lx_elf:5423
```cpp
upx_uint64_t const w = get_te64(&bitmask[(n_bitmask -1) & (h>>6)]);
```

## How can we reproduce the issue?
1. compile upx with address-sanitize
2. execute cmd
```bash
upx.out -df $PoC -o /dev/null
```
[Poc](https://github.com/14isnot40/vul_discovery/blob/master/upx/df/hbo_PackLinuxElf64__elf_lookup5423) can be found here.


## Please tell us details about your environment.
* UPX version used (`upx --version`):
```bash
upx 4.0.0-git-c6b9e3c62d15 (latest-devel-branch)
UCL data compression library 1.03
zlib data compression library 1.2.8
LZMA SDK version 4.43
```
* Host Operating System and version:
Ubuntu 16.04 64-bit
* Host CPU architecture:
Intel(R) Core(TM) i5-6200U CPU @ 2.30GHz with 8GB 
* Target Operating System and version:
 same as Host
* Target CPU architecture:
 same as Host



Comments:
Comment by jreiser on 2020-05-28 00:15:05+00:00:
Fixed on `devel` branch by above commit.

---

Comment by jreiser on 2023-04-17 18:34:13+00:00:
Verified closed in official release  [upx-4.0.2](https://github.com/upx/upx/releases/tag/v4.0.2) of Jan.30, 2023:
```
$ valgrind $UPX402 -df -o /dev/null hbo_PackLinuxElf64__elf_lookup5423
==27034== Memcheck, a memory error detector
==27034== Copyright (C) 2002-2022, and GNU GPL'd, by Julian Seward et al.
==27034== Using Valgrind-3.19.0 and LibVEX; rerun with -h for copyright info
==27034== Command: /home2/upx/upx-4.0.2-amd64_linux/upx -df -o /dev/null hbo_PackLinuxElf64__elf_lookup5423
==27034== 
                       Ultimate Packer for eXecutables
                          Copyright (C) 1996 - 2023
UPX 4.0.2       Markus Oberhumer, Laszlo Molnar & John Reiser   Jan 30th 2023

        File size         Ratio      Format      Name
   --------------------   ------   -----------   -----------
upx: hbo_PackLinuxElf64__elf_lookup5423: CantUnpackException: bad DT_STRSZ 0

Unpacked 0 files.
==27034== 
==27034== HEAP SUMMARY:
==27034==     in use at exit: 0 bytes in 0 blocks
==27034==   total heap usage: 0 allocs, 0 frees, 0 bytes allocated
==27034== 
==27034== All heap blocks were freed -- no leaks are possible
==27034== 
==27034== For lists of detected and suppressed errors, rerun with: -s
==27034== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 0 from 0)
$ 
```

Build script:
#!/bin/bash -eu
# Minimized build script with only core build commands
set -eu
sed -i 's/ \&\& __clang_major__ < 15//m' /src/upx/src/util/util.cpp
mkdir -p build/debug
cd build/debug
cmake ../..
    cmake --build . --target $fuzz_basename -v

Dockerfile:
FROM hwiwonlee/secb.base:latest
RUN apt-get update && apt-get install -y make autoconf automake libtool cmake
RUN git clone https://github.com/upx/upx upx
RUN git -C upx checkout e0bf4609938b0b4d2e83469fac00206a771429e5
WORKDIR $SRC/upx
COPY build.sh $SRC/

Additional files: