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

================= Bug Report (1/1) ==================
## Source: GitHub Issue
## URL: https://github.com/upx/upx/issues/287
## Description:
Issue: upx/upx#287
Title: canUnpack@p_vmlinx.cpp:583___buffer-overflow
State: closed
Created by: aheroine
Created at: 2019-07-19 06:25:38+00:00

Issue Body:
<!---

IF YOU REMOVE THIS TEMPLATE WE WILL CLOSE YOUR ISSUE WITHOUT RESPONSE.
Just read it and fill in the details we're asking, it saves so much of our time. Thanks!

-->

## What's the problem (or question)?
<!--- If describing a bug, tell us what happens instead of the expected behavior -->
<!--- If suggesting a change/improvement, explain the difference from current behavior -->
An issue was discovered in upx 3.95, There is a/an buffer-overflow in function canUnpack at p_vmlinx.cpp:583

upx.out -l @@ /dev/null

## What should have happened?
<!--- If you're describing a bug, tell us what should happen -->
<!--- If you're suggesting a change/improvement, tell us how it should work -->
list compressed file
## Do you have an idea for a solution?
<!--- Not obligatory, but suggest a fix/reason for the bug, -->
<!--- or ideas how to implement the addition or change -->

check for buffer overflow correctly

## How can we reproduce the issue?
<!--- Provide unambiguous set of steps to reproduce this bug. Include code to reproduce, if relevant -->
 upx.out -l @@ /dev/null

 the poc is attached [poc](https://github.com/aheroine/libming-bin/raw/master/crashes/upx/poc-buffer-overflow)

### source

```c
 574     // check for .text .note .note  and sane (.sh_size + .sh_offset)
 575     p_note0 = p_note1 = p_text = 0;
 576     int j;
 577     Shdr *p;
 578     for (p= shdri, j= ehdri.e_shnum; --j>=0; ++p) {
 579         if ((unsigned)file_size < (p->sh_size + p->sh_offset)
 580         ||  shstrsec->sh_size < (5+ p->sh_name) ) {
 581             continue;
 582         }
 583         if (0==strcmp(".text", shstrtab + p->sh_name)) {
 584             p_text = p;
 585         }
 586         if (0==strcmp(".note", shstrtab + p->sh_name)) {
 587             if (0==p_note0) {
 588                 p_note0 = p;
 589             } else
 590             if (0==p_note1) {
 591                 p_note1 = p;
 592             }
 593         }
 594     }
```
### debug

```c
    pwndbg> p shstrtab 
    $5 = 0x611000009f00 "\200"
    pwndbg> p p->sh_name 
    $6 = {
    d = "\377\377\377\377"
    }
    pwndbg> p sizeof(p->sh_name )
    $7 = 4
    pwndbg> p/x p->sh_name 
    $8 = {
    d = {0xff, 0xff, 0xff, 0xff}
    }
    pwndbg>
```

### bug report

```txt
ASAN:SIGSEGV
=================================================================
==8931==ERROR: AddressSanitizer: SEGV on unknown address 0x611100009eff (pc 0x7f66aca7d05e bp 0x7fff0bf97d90 sp 0x7fff0bf97520 T0)
    #0 0x7f66aca7d05d  (/usr/lib/x86_64-linux-gnu/libasan.so.2+0x4705d)
    #1 0x6d3087 in PackVmlinuxBase<N_Elf::ElfClass_32<N_BELE_CTP::LEPolicy> >::canUnpack() /home/jl/work/projects/upx/upx/src/p_vmlinx.cpp:583
    #2 0x7a7e1d in try_unpack /home/jl/work/projects/upx/upx/src/packmast.cpp:114
    #3 0x7ac2e4 in PackMaster::visitAllPackers(Packer* (*)(Packer*, void*), InputFile*, options_t const*, void*) /home/jl/work/projects/upx/upx/src/packmast.cpp:178
    #4 0x7b5282 in PackMaster::getUnpacker(InputFile*) /home/jl/work/projects/upx/upx/src/packmast.cpp:248
    #5 0x7b694b in PackMaster::list() /home/jl/work/projects/upx/upx/src/packmast.cpp:279
    #6 0x8604db in do_one_file(char const*, char*) /home/jl/work/projects/upx/upx/src/work.cpp:164
    #7 0x8615fa in do_files(int, int, char**) /home/jl/work/projects/upx/upx/src/work.cpp:271
    #8 0x468b28 in main /home/jl/work/projects/upx/upx/src/main.cpp:1539
    #9 0x7f66ab1cd82f in __libc_start_main (/lib/x86_64-linux-gnu/libc.so.6+0x2082f)
    #10 0x4030f8 in _start (/home/jl/work/up_projects/fuzz-upx/crashes/upx.out.debug+0x4030f8)

AddressSanitizer can not provide additional info.
SUMMARY: AddressSanitizer: SEGV ??:0 ??
==8931==ABORTING
```
## Please tell us details about your environment.
<!--- Include as many relevant details about the environment you experienced the bug in -->
* UPX version used (`upx --3.95`):
* Host Operating System and version: ubuntu 16.04
* Host CPU architecture: Intel(R) Core(TM) i5-7200U CPU @ 2.50GHz
* Target Operating System and version: ubuntu 16.04
* Target CPU architecture: Intel(R) Core(TM) i5-7200U CPU @ 2.50GHz



Comments:
Comment by jreiser on 2019-07-19 14:28:17+00:00:
Diagnosed by tip of `devel`:
```
$ ../upx.out -o foo poc-buffer-overflow
                       Ultimate Packer for eXecutables
                          Copyright (C) 1996 - 2019
UPX git-593a69+ Markus Oberhumer, Laszlo Molnar & John Reiser   Feb 24th 2019

        File size         Ratio      Format      Name
   --------------------   ------   -----------   -----------
upx.out: poc-buffer-overflow: UnknownExecutableFormatException

Packed 0 files.

WARNING: this is an unstable beta version - use for testing only! Really.
```
That might not be the best diagnosis, but at least it has no buffer overflow.

---

Comment by jreiser on 2019-07-21 14:43:02+00:00:
Fixed on `devel` branch by commit above.

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 7a3637ff5a800b8bcbad20ae7f668d8c8449b014
WORKDIR $SRC/upx
COPY build.sh $SRC/

Additional files: