Skip to main content
← All libraries
Image · C++

How to fuzz libheif

HEIF is the iPhone default image format — and libheif parses deeply nested container boxes.

libheif wraps HEVC and AV1 codecs inside an ISOBMFF container that can carry deeply nested box structures. The combination of C++ container logic, third-party codec delegates, and complex metadata handling (Exif, XMP, depth maps) creates a wide attack surface frequently exercised on iOS devices.

Common bug classes

  • Heap buffer overflow in ftyp/mdat box length arithmetic
  • Out-of-bounds read in colour information box parsing
  • Use-after-free in image item reference resolution
  • Integer overflow in tiled image reassembly
  • Null dereference on missing mandatory box types

Recommended setup

Fuzzers

  • AFL++
  • libFuzzer
  • Honggfuzz

Sanitizers

  • ASan
  • UBSan
  • MSan

Harness scaffold

#include <stdint.h>
#include <stddef.h>
#include <libheif/heif.h>

int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) {
  struct heif_context *ctx = heif_context_alloc();
  if (!ctx) return 0;
  struct heif_error err =
      heif_context_read_from_memory_without_copy(ctx, data, size, NULL);
  if (err.code == heif_error_Ok) {
    struct heif_image_handle *hdl = NULL;
    heif_context_get_primary_image_handle(ctx, &hdl);
    if (hdl) {
      struct heif_image *img = NULL;
      heif_decode_image(hdl, &img, heif_colorspace_RGB,
                        heif_chroma_interleaved_RGBA, NULL);
      if (img) heif_image_release(img);
      heif_image_handle_release(hdl);
    }
  }
  heif_context_free(ctx);
  return 0;
}

Save this as fuzz_target.cc, build with your compiler + sanitizer flags, and you have a working starting point.

Start fuzzing libheif on Fuzze.rs →

Push the harness above + a Dockerfile. First month 50% off.