Open-source project
google/honggfuzz avatar
google/honggfuzz

google/honggfuzz: a coverage-driven fuzzer you build with make and drive from the command line

Security oriented software fuzzer. Supports evolutionary, feedback-driven fuzzing based on code coverage (SW and HW based)

3,387 stars539 forksCApache-2.0

At a glance

What is it?
Honggfuzz is a general-purpose, feedback-driven fuzzer that uses software and hardware code coverage to evolve inputs. It is aimed at engineers fuzzing C, C++ or Rust targets on Linux, macOS, Android and the BSDs, and it is driven from a corpus directory and a compiler wrapper rather than a project file.
Who is it for?
Adopt honggfuzz if you have a native binary or library, a Linux or macOS build host, and a corpus directory you can point the fuzzer at; the compiler wrappers in hfuzz_cc/ and the persistent mode flag -P are the two things to learn first. Do not adopt it if you need a managed-runtime or JavaScript target, or if you cannot run a long-lived process with ptrace available, since the README describes ptrace as the mechanism behind signal and crash detection.
Can I use it commercially?
Yes. Apache-2.0 is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
Is it still maintained?
Yes. The repository last received commits 5 days ago.
What is it written in?
Mainly C, according to GitHub's language statistics.

Answers come from the project's GitHub data, last synced on September 28, 2026, and from our analysis. They are not legal advice.

Editorial analysis

The problem honggfuzz solves: turning a binary into a fuzzing target without writing a harness framework

Most teams that want to fuzz a native codebase hit the same wall. They have a parser, a protocol handler, or a file format reader written in C or C++, and they want to feed it malformed input until it crashes. What they do not have is a harness, a mutation engine, a coverage map, and a crash triage loop. Honggfuzz is the README's answer to that: "A security-oriented, feedback-driven, evolutionary fuzzer" that is "general-purpose" and can be pointed at an existing binary.

The intended user is a security engineer or a maintainer who already compiles the target themselves. The README's own example list is telling: examples/apache-httpd, examples/bind, examples/openssl, examples/libjpeg, examples/libpng, examples/libxml2, examples/linux_kernel_ip. These are not toy programs. They are large C projects with build systems, configuration files, and long-running server processes. Honggfuzz assumes you know how to build one of those, and it supplies the part you do not want to write.

The second audience is continuous integration. The README lists Apache HTTP Server and Systemd as CI fuzzing users, and Google OSS-Fuzz as a continuous fuzzing user. That matters because it sets the operational bar: the tool is expected to run unattended, restart crashed children, and keep going.

What it is not is a unit-testing framework. There is no assertion library, no test runner, and no reporting format aimed at a dashboard. The output is a corpus that grows and a set of crash artifacts.

How coverage feedback and the ptrace supervisor fit together

The mechanism has three parts, and the README names all three.

First, instrumentation. The hfuzz_cc/ directory contains compiler wrappers, hfuzz-clang and hfuzz-clang++, that add coverage instrumentation at compile time. This is the software-coverage path. The README also claims hardware coverage through "Intel BTS/PT", which is the processor's Branch Trace Store and Processor Trace facilities. Those two paths are alternatives, not layers: software instrumentation works anywhere clang works, hardware tracing depends on the CPU and the kernel support around it.

Second, the engine. The README describes it as "Multi-process and multi-threaded", and says persistent fuzzing reaches "iteration speeds up to 1M/sec". That number comes from the project's own documentation and should be treated as an upper bound for in-process test APIs, not a rate you should expect against a binary that starts a fresh process per input.

Third, the supervisor. "Uses low-level APIs (ptrace) to detect hijacked signals and hidden crashes." This is the design decision that separates honggfuzz from fuzzers that simply wait for a non-zero exit code. A target that installs a SIGSEGV handler and recovers would look healthy to a naive runner. Under ptrace, the README says, those hijacked signals are visible. The cost is that ptrace has to be permitted, which rules out some container and sandbox configurations.

The data flow is therefore: wrapper-instrumented binary writes coverage, the engine mutates the corpus and selects inputs that reach new coverage, the supervisor watches the child process, and the report layer writes out anything that crashed. The repository layout reflects this split, with fuzz.c, input.c, mangle.c, report.c, subproc.c and sanitizers.c as separate translation units.

Installing honggfuzz and running a first target

The README gives dependencies per platform. On Ubuntu or Debian the package list is explicit:

bash
sudo apt-get install binutils-dev libunwind-dev libblocksruntime-dev clang

On macOS the README says Xcode 10.8 or later is required, along with libblocksruntime. The build itself is a single make invocation from the source tree:

bash
make

The README states that compilation wrappers are created in hfuzz_cc/. If that directory is empty after the build, the instrumentation step will fail later, so check it before going further. The repository also ships a Dockerfile that installs libipt-dev, libunwind8-dev, binutils-dev and clang on ubuntu:rolling, clones the repository with --depth=1, runs make, and copies the resulting binary to /bin. That is the shortest path if you would rather not manage the dependencies on the host.

Compile a target through the wrapper. The README's example for C is:

bash
./hfuzz_cc/hfuzz-clang -o my_target my_target.c

For C++ the equivalent wrapper is hfuzz-clang++. Then run the fuzzer against a corpus directory and the binary:

bash
./honggfuzz -i input_dir/ -- ./my_target ___FILE___

The README notes that ___FILE___ is a placeholder for the input filename generated by honggfuzz, and that input_dir can be empty, because the README says the tool can "automatically build a valid input set" from nothing. What you should see is the fuzzer starting, reporting its workers, and beginning to write files into the corpus as it discovers inputs. The persistent-mode variant drops the placeholder:

bash
./honggfuzz -P -i input_dir/ -- ./my_target

Persistent mode requires the target to expose a test API that the fuzzer can call in a loop, so it is not a drop-in replacement for the first command. The README points to docs/USAGE.md for detailed options and to examples/ for Apache, OpenSSL and BIND configurations.

Where honggfuzz gets in the way

The most concrete limitation is persistent mode. The README presents it as the fast path, and it is, but it demands that you restructure the target so a single process can be called repeatedly. For a program whose main() reads a file and exits, that restructuring is real work, and it changes the code you are testing. A fuzzer that requires you to modify the target weakens the claim that you are testing the shipped artifact.

The supervisor is the second constraint. ptrace is powerful and it is also frequently restricted. Docker's default seccomp profile blocks ptrace unless you add the capability, and hardened production hosts often disable it outright. The README does not document a fallback path for environments where ptrace is unavailable, so if your build farm runs in a locked-down container you should confirm this before planning around it.

Platform coverage is broader on paper than in practice. The README lists Linux, macOS, Android, NetBSD, FreeBSD and Windows via Cygwin. The repository layout backs that up with separate linux/, mac/, netbsd/, posix/ and android/ directories, plus a qemu_mode/ directory for targets that cannot be instrumented at compile time. Windows support is qualified as Cygwin, which is a compatibility layer rather than native support, and the README does not describe a native Windows build.

Finally, there is no documented rollback or corpus-pruning story in the README. A long-running campaign accumulates inputs, and nothing in the README explains how to shrink that set. The release cadence is also worth noting: the most recent tagged version is 2.6 from 2023-09-21, with an oss-fuzz rolling release from 2024-07-20. The last push to master was on 2026-06-19, so the tree is moving even though tagged releases are infrequent.

honggfuzz against afl++ and libFuzzer

The comparison people search for most is honggfuzz versus afl++. The difference is in the supervisor and the instrumentation model. AFL-family fuzzers historically relied on compiler-injected instrumentation and a shared-memory coverage map, with crash detection driven by the child's exit status and signals. Honggfuzz adds ptrace-based supervision, which the README describes as catching "hijacked signals and hidden crashes". If your target catches SIGSEGV and continues, that distinction is the whole argument. If it does not, the two tools are closer than the marketing suggests.

Against libFuzzer the split is architectural rather than a matter of coverage quality. libFuzzer is an in-process library that you link into a harness; the harness owns main() and the fuzzer runs inside it. Honggfuzz is an external driver that launches your binary, with persistent mode as an opt-in fast path rather than the only mode. That makes honggfuzz the easier fit when you cannot modify the build to link a fuzzing library, and the harder fit when you want the fuzzer to be just another object file in your existing test binary.

There is also a Rust angle, since honggfuzz-rs is listed among the projects using honggfuzz. That crate exists because the C tool's natural interface is a compiled binary, and Rust projects needed a bridge. If you are fuzzing Rust, the crate is the entry point the README points you toward rather than the C binary directly.

Licence, upgrade cost and what the repository commits you to

Honggfuzz is Apache License 2.0, and the README states plainly that it is "NOT an official Google product". That sentence matters more than the licence header. It means the project does not carry a Google product support commitment, and you should read the CONTRIBUTING.md and CHANGELOG files in the repository root for how changes are handled rather than assuming a support relationship.

Apache-2.0 is permissive: it includes an express patent grant and permits commercial and closed-source use, with the usual requirements around notices and the licence text. That is a general description of the licence, not legal advice for your situation.

Upgrade cost is low by construction. The tool is a single binary plus a wrapper directory, built from source with make, with no runtime package manager and no service to deploy. The Dockerfile in the repository pins ubuntu:rolling, which is a moving base image, so a rebuild months apart can pull different system libraries. If reproducibility matters for your fuzzing infrastructure, that is the line to change.

The dependency list is the real upgrade surface: binutils-dev, libunwind-dev, libblocksruntime-dev and clang on Linux, plus libipt-dev in the Dockerfile for Intel PT. A distribution that renames or drops one of those packages will break the build before it breaks anything else.

Editorial conclusion

Adopt honggfuzz if you have a native binary or library, a Linux or macOS build host, and a corpus directory you can point the fuzzer at; the compiler wrappers in hfuzz_cc/ and the persistent mode flag -P are the two things to learn first. Do not adopt it if you need a managed-runtime or JavaScript target, or if you cannot run a long-lived process with ptrace available, since the README describes ptrace as the mechanism behind signal and crash detection. Before trusting it, verify that make completes on your distribution's clang and that the wrapper binaries appear in hfuzz_cc/, then confirm the fuzzer writes inputs and crashes into the directories you expect rather than into the working tree.

Frequently asked questions

How do I install honggfuzz on Linux?

Install the dependencies listed in the README (binutils-dev, libunwind-dev, libblocksruntime-dev and clang on Ubuntu or Debian), then run make from the source tree. The wrappers appear in hfuzz_cc/. The repository also ships a Dockerfile that performs the same steps on ubuntu:rolling.

Does honggfuzz work on Windows?

The README lists Windows support through Cygwin, alongside Linux, macOS, Android, NetBSD and FreeBSD. It does not describe a native Windows build, and the repository contains platform directories for linux, mac, netbsd, posix and android rather than a native Windows one.

What is the difference between honggfuzz and libFuzzer?

libFuzzer is linked into your harness as a library and runs in-process, while honggfuzz is an external driver that launches your binary and offers persistent mode as an opt-in fast path. The README describes honggfuzz as multi-process and multi-threaded, with a ptrace-based supervisor for detecting hijacked signals.

How do I fuzz Rust code with honggfuzz?

The README lists honggfuzz-rs as the crate used for fuzzing Rust code, alongside projects such as Bitcoin Core and OSS-Fuzz that use honggfuzz itself. The README does not document the crate's API, so the crate's own documentation is the place to look.

Official sources

  1. google/honggfuzz on GitHub
  2. License: Apache-2.0
  3. Project website
  4. README
  5. Releases
Add this badge to your README

If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.

Add this badge to your README

markdown
[![Hysen Labs](https://hysenlabs.com/badge/google-honggfuzz.svg)](https://hysenlabs.com/projects/google-honggfuzz)