Skip to main content
← All libraries
Binary · C

How to fuzz libelf

ELF object file library used by every Linux toolchain and debugger

libelf and elfutils' libdw are loaded by perf, eu-readelf, valgrind, and dozens of debugging tools to parse untrusted ELF binaries (often from crashed processes or malware). The parser surface is wide and CVEs continue to land.

Common bug classes

  • Heap overflows in ELF program-header table walks
  • Out-of-bounds reads on malformed section name tables
  • Integer overflow in DWARF abbrev / line-program decoding

Recommended setup

Fuzzers

  • libFuzzer
  • AFL++

Sanitizers

  • ASan
  • UBSan

Harness scaffold

#include <libelf.h>
#include <gelf.h>
#include <fcntl.h>
#include <unistd.h>
#include <stdio.h>
#include <stddef.h>
#include <stdint.h>

extern "C" int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) {
  int fd = open("/tmp/elf_fuzz.bin", O_CREAT | O_WRONLY | O_TRUNC, 0600);
  if (fd < 0) return 0;
  if (write(fd, data, size) != (ssize_t)size) { close(fd); return 0; }
  close(fd);

  elf_version(EV_CURRENT);
  fd = open("/tmp/elf_fuzz.bin", O_RDONLY);
  Elf *e = elf_begin(fd, ELF_C_READ, nullptr);
  if (e) {
    GElf_Ehdr ehdr;
    if (gelf_getehdr(e, &ehdr)) {
      Elf_Scn *scn = nullptr;
      while ((scn = elf_nextscn(e, scn)) != nullptr) {
        GElf_Shdr sh;
        gelf_getshdr(scn, &sh);
      }
    }
    elf_end(e);
  }
  close(fd);
  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-2021-33294
  • CVE-2024-25260
Start fuzzing libelf on Fuzze.rs →

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