Crates.io | honggfuzz |
lib.rs | honggfuzz |
version | 0.5.56 |
source | src |
created_at | 2018-02-06 21:09:32.205481 |
updated_at | 2024-05-21 12:23:57.876863 |
description | Fuzz your Rust code with Google-developped Honggfuzz ! |
homepage | https://github.com/rust-fuzz/honggfuzz-rs/blob/master/README.md |
repository | https://github.com/rust-fuzz/honggfuzz-rs |
max_upload_size | |
id | 49906 |
size | 33,804,265 |
Fuzz your Rust code with Google-developed Honggfuzz !
Honggfuzz is a security oriented fuzzer with powerful analysis options. Supports evolutionary, feedback-driven fuzzing based on code coverage (software- and hardware-based).
cc
make
libbfd.h
libunwind.h
For example on Debian and its derivatives:
sudo apt install build-essential binutils-dev libunwind-dev libblocksruntime-dev liblzma-dev
Install honggfuzz commands to build with instrumentation and fuzz
# installs hfuzz and honggfuzz subcommands in cargo
cargo install honggfuzz
Add to your dependencies
[dependencies]
honggfuzz = "0.5"
Create a target to fuzz
use honggfuzz::fuzz;
fn main() {
// Here you can parse `std::env::args and
// setup / initialize your project
// You have full control over the loop but
// you're supposed to call `fuzz` ad vitam aeternam
loop {
// The fuzz macro gives an arbitrary object (see `arbitrary crate`)
// to a closure-like block of code.
// For performance reasons, it is recommended that you use the native type
// `&[u8]` when possible.
// Here, this slice will contain a "random" quantity of "random" data.
fuzz!(|data: &[u8]| {
if data.len() != 3 {return}
if data[0] != b'h' {return}
if data[1] != b'e' {return}
if data[2] != b'y' {return}
panic!("BOOM")
});
}
}
Fuzz for fun and profit !
# builds with fuzzing instrumentation and then fuzz the "example" target
cargo hfuzz run example
Once you got a crash, replay it easily in a debug environment
# builds the target in debug mode and replays automatically the crash in rust-lldb
cargo hfuzz run-debug example hfuzz_workspace/*/*.fuzz
You can also build and run your project without compile-time software instrumentation (LLVM's SanCov passes)
This allows you for example to try hardware-only feedback driven fuzzing:
# builds without fuzzing instrumentation and then fuzz the "example" target using hardware-based feedback
HFUZZ_RUN_ARGS="--linux_perf_ipt_block --linux_perf_instr --linux_perf_branch" cargo hfuzz run-no-instr example
Clean
# a wrapper on "cargo clean" which cleans the fuzzing_target directory
cargo hfuzz clean
Version
cargo hfuzz version
RUSTFLAGS
You can use RUSTFLAGS
to send additional arguments to rustc
.
For instance, you can enable the use of LLVM's sanitizers.
This is a recommended option if you want to test your unsafe
rust code but it will have an impact on performance.
RUSTFLAGS="-Z sanitizer=address" cargo hfuzz run example
HFUZZ_BUILD_ARGS
You can use HFUZZ_BUILD_ARGS
to send additional arguments to cargo build
.
HFUZZ_RUN_ARGS
You can use HFUZZ_RUN_ARGS
to send additional arguments to honggfuzz
.
See USAGE for the list of those.
For example:
# 1 second of timeout
# use 12 fuzzing thread
# be verbose
# stop after 1000000 fuzzing iteration
# exit upon crash
HFUZZ_RUN_ARGS="-t 1 -n 12 -v -N 1000000 --exit_upon_crash" cargo hfuzz run example
HFUZZ_DEBUGGER
By default we use rust-lldb
but you can change it to rust-gdb
, gdb
, /usr/bin/lldb-7
...
CARGO_TARGET_DIR
Target compilation directory, defaults to hfuzz_target
to not clash with cargo build
's default target
directory.
HFUZZ_WORKSPACE
Honggfuzz working directory, defaults to hfuzz_workspace
.
HFUZZ_INPUT
Honggfuzz input files (also called "corpus"), defaults to $HFUZZ_WORKSPACE/{TARGET}/input
.
Sometimes, it is necessary to make some specific adaptation to your code to yield a better fuzzing efficiency.
For instance:
Make you software behavior as much as possible deterministic on the fuzzing input
Never ever call std::process::exit()
.
Disable logging and other unnecessary functionalities.
Try to avoid modifying global state when possible.
Do not set up your own panic hook when run with cfg(fuzzing)
When building with cargo hfuzz
, the argument --cfg fuzzing
is passed to rustc
to allow you to condition the compilation of those adaptations thanks to the cfg
macro like so:
#[cfg(fuzzing)]
let mut rng = rand_chacha::ChaCha8Rng::from_seed(&[0]);
#[cfg(not(fuzzing))]
let mut rng = rand::thread_rng();
Also, when building in debug mode, the fuzzing_debug
argument is added in addition to fuzzing
.
For more information about conditional compilation, please see the reference.
There is other projects providing Rust fuzzing support at github.com/rust-fuzz.
You'll find support for AFL and LLVM's LibFuzzer and there is also a trophy case ;-) .
This crate was inspired by those projects!