Project: libheif (strukturag/libheif), language: c++
Vulnerability instance: libheif.cve-2023-49462
Sanitizer: address

================= Bug Report (1/1) ==================
## Source: GitHub Issue
## URL: https://github.com/strukturag/libheif/issues/1043
## Description:
Issue: strukturag/libheif#1043
Title: SEGV libheif/libheif/exif.cc:55 in read16
State: closed
Created by: fdu-sec
Created at: 2023-11-22 09:15:02+00:00

Issue Body:
### Description

SEGV `libheif/libheif/exif.cc:55` in `read16`

### Version

```
 heif-convert  libheif version: 1.17.5
-------------------------------------------
Usage: heif-convert [options]  <input-image> [output-image]

The program determines the output file format from the output filename suffix.
These suffixes are recognized: jpg, jpeg, png, y4m. If no output filename is specified, 'jpg' is used.

Options:
  -h, --help                     show help
  -v, --version                  show version
  -q, --quality                  quality (for JPEG output)
  -o, --output FILENAME          write output to FILENAME (optional)
  -d, --decoder ID               use a specific decoder (see --list-decoders)
      --with-aux                 also write auxiliary images (e.g. depth images)
      --with-xmp                 write XMP metadata to file (output filename with .xmp suffix)
      --with-exif                write EXIF metadata to file (output filename with .exif suffix)
      --skip-exif-offset         skip EXIF metadata offset bytes
      --no-colons                replace ':' characters in auxiliary image filenames with '_'
      --list-decoders            list all available decoders (built-in and plugins)
      --quiet                    do not output status messages to console
  -C, --chroma-upsampling ALGO   Force chroma upsampling algorithm (nn = nearest-neighbor / bilinear)
      --png-compression-level #  Set to integer between 0 (fastest) and 9 (best). Use -1 for default.
```

### Replay

```
cd libheif
mkdir build && cd build
CC="gcc -fsanitize=address" CXX="g++ -fsanitize=address" cmake --preset=release ..
make -j
./examples/heif-convert ./poc test.png
```

### ASAN

```
==1926429==ERROR: AddressSanitizer: SEGV on unknown address 0x60b080000729 (pc 0x55abe2b1012c bp 0x000000000000 sp 0x7ffe0b2df5a0 T0)
==1926429==The signal is caused by a READ memory access.
    #0 0x55abe2b1012c in read16 /eva/put/libheif/libheif/exif.cc:55
    #1 0x55abe2b1012c in find_exif_tag /eva/put/libheif/libheif/exif.cc:103
    #2 0x55abe2b1136b in modify_exif_tag_if_it_exists(unsigned char*, int, unsigned short, unsigned short) /eva/put/libheif/libheif/exif.cc:124
    #3 0x55abe2b1136b in modify_exif_orientation_tag_if_it_exists(unsigned char*, int, unsigned short) /eva/put/libheif/libheif/exif.cc:140
    #4 0x55abe2b16c75 in PngEncoder::Encode(heif_image_handle const*, heif_image const*, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&) /eva/put/libheif/examples/encoder_png.cc:126
    #5 0x55abe2b00c99 in main /eva/put/libheif/examples/heif_convert.cc:509
    #6 0x7fb15dc29d8f in __libc_start_call_main ../sysdeps/nptl/libc_start_call_main.h:58
    #7 0x7fb15dc29e3f in __libc_start_main_impl ../csu/libc-start.c:392
    #8 0x55abe2b09254 in _start (/eva/asan-bin/NestFuzz/libheif/heif-convert+0x15254)

AddressSanitizer can not provide additional info.
SUMMARY: AddressSanitizer: SEGV /eva/put/libheif/libheif/exif.cc:55 in read16
==1926429==ABORTING
```

### POC

[poc](https://github.com/fdu-sec/poc/raw/main/libheif/poc2)

### Environment

```
Description:	Ubuntu 22.04.2 LTS
gcc (Ubuntu 11.4.0-1ubuntu1~22.04) 11.4.0
```

### Credit

Yuchuan Meng ([Fudan University](https://secsys.fudan.edu.cn/))


Comments:
Comment by bradh on 2023-11-30 20:18:54+00:00:
A fix for this is in work.

---

Comment by carnil on 2023-12-07 20:32:07+00:00:
This seems to be CVE-2023-49462

Build script:
#!/bin/bash -eu
# Minimized build script with only core build commands
set -eu
export DEPS_PATH=$SRC/deps
mkdir -p $DEPS_PATH
cd $SRC/x265/build/linux
cmake -G "Unix Makefiles" \
    -DCMAKE_C_COMPILER=$CC -DCMAKE_CXX_COMPILER=$CXX \
    -DCMAKE_C_FLAGS="$CFLAGS" -DCMAKE_CXX_FLAGS="$CXXFLAGS" \
    -DCMAKE_INSTALL_PREFIX="$DEPS_PATH" \
    -DENABLE_SHARED:bool=off \
    ../../source
make clean -j$(nproc)
make -j$(nproc) x265-static
make install -j$(nproc)
cd $SRC/libde265
./autogen.sh
./configure \
    --prefix="$DEPS_PATH" \
    --disable-shared \
    --enable-static \
    --disable-dec265 \
    --disable-sherlock265 \
    --disable-hdrcopy \
    --disable-enc265 \
    --disable-acceleration_speed
make -j$(nproc)
mkdir -p $SRC/aom/build/linux
cd $SRC/aom/build/linux
  -DENABLE_SHARED:bool=off -DCONFIG_PIC=1 \
  -DENABLE_EXAMPLES=0 -DENABLE_DOCS=0 -DENABLE_TESTS=0 \
  -DCONFIG_SIZE_LIMIT=1 \
  -DDECODE_HEIGHT_LIMIT=12288 -DDECODE_WIDTH_LIMIT=12288 \
  -DDO_RANGE_CHECK_CLAMP=1 \
  -DAOM_MAX_ALLOCABLE_MEMORY=536870912 \
  -DAOM_TARGET_CPU=generic \
  ../../
cd $SRC/libheif
mkdir -p build
cd build
cmake .. --preset=fuzzing \
      -DFUZZING_COMPILE_OPTIONS="" \
      -DFUZZING_LINKER_OPTIONS="$LIB_FUZZING_ENGINE" \
      -DFUZZING_C_COMPILER=$CC -DFUZZING_CXX_COMPILER=$CXX \
      -DWITH_DEFLATE_HEADER_COMPRESSION=OFF

Dockerfile:
FROM hwiwonlee/secb.base:latest
RUN apt-get update && apt-get install -y autoconf automake build-essential cmake libtool make mercurial pkg-config yasm
RUN git clone https://github.com/strukturag/libheif libheif
RUN git -C libheif checkout 82219b903001305fd916874a29dd372d92927d48
WORKDIR $SRC/libheif
COPY build.sh $SRC/

Additional files: