Skip to main content
← All libraries
Archive · C

How to fuzz libarchive

One library, 30 archive formats — each is a separate bug surface with shared allocation logic.

libarchive is the extraction engine behind BSD tar, macOS Archive Utility, and many package managers. Its unified API hides per-format parsers for tar, cpio, pax, ISO9660, 7-Zip, RAR, XAR, and more — all sharing common allocation helpers that make cross-format integer overflows easy to introduce.

Common bug classes

  • Heap buffer overflow in tar extended header length arithmetic
  • Integer overflow in ISO9660 directory record size field
  • Out-of-bounds read in 7-Zip LZMA property block parsing
  • Use-after-free in multi-volume archive state machine
  • Path traversal via crafted symlink entries (security logic bug)

Recommended setup

Fuzzers

  • AFL++
  • libFuzzer
  • Honggfuzz

Sanitizers

  • ASan
  • UBSan

Harness scaffold

#include <stdint.h>
#include <stddef.h>
#include <archive.h>
#include <archive_entry.h>

int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) {
  struct archive *a = archive_read_new();
  archive_read_support_filter_all(a);
  archive_read_support_format_all(a);
  if (archive_read_open_memory(a, data, size) == ARCHIVE_OK) {
    struct archive_entry *entry;
    while (archive_read_next_header(a, &entry) == ARCHIVE_OK)
      archive_read_data_skip(a);
  }
  archive_read_free(a);
  return 0;
}

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

Notable CVEs found by fuzzing

  • CVE-2019-18408
  • CVE-2021-31566
Start fuzzing libarchive on Fuzze.rs →

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