Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Allow more closures #10

Merged
merged 4 commits into from
Aug 28, 2018
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -175,6 +175,7 @@ For instance:
- Never ever call `std::process::exit()`.
- Disable logging and other unnecessary functionnalities.
- 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 thoses adaptations thanks to the `cfg` macro like so:
Expand Down
9 changes: 9 additions & 0 deletions example/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,11 @@ fn main() {
// Here you can parse `std::env::args and
// setup / initialize your project

// You should avoid as much as possible global states.
// This example is just there to test that this works nevertheless.
// For more information, check out the `std::panic::UnwindSafe` trait.
let mut some_global_state = 0u64;

// You have full control over the loop but
// you're supposed to call `fuzz` ad vitam aeternam
loop {
Expand All @@ -13,6 +18,9 @@ fn main() {
// `&[u8]` when possible.
// Here, this slice will contain a "random" quantity of "random" data.
fuzz!(|data: &[u8]| {
// Try to access the global state across the unwind boundary
some_global_state += 1;

if data.len() != 6 {return}
if data[0] != b'q' {return}
if data[1] != b'w' {return}
Expand All @@ -21,6 +29,7 @@ fn main() {
if data[4] != b't' {return}
if data[5] != b'y' {return}
panic!("BOOM")

});
}
}
11 changes: 8 additions & 3 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -209,6 +209,9 @@ extern "C" {
///
/// For perstistent fuzzing to work, you have to call it ad vita aeternam in an infinite loop.
///
/// The closure is assumed to be unwind-safe, which might be unsafe. For more info, check the
/// [`std::panic::UnwindSafe`] trait.
///
/// ```rust,should_panic
/// # extern crate honggfuzz;
/// # use honggfuzz::fuzz;
Expand Down Expand Up @@ -249,7 +252,7 @@ lazy_static! {
}

#[cfg(all(fuzzing, not(fuzzing_debug)))]
pub fn fuzz<F>(closure: F) where F: FnOnce(&[u8]) + std::panic::UnwindSafe {
pub fn fuzz<F>(closure: F) where F: FnOnce(&[u8]) {
// sets panic hook if not already done
lazy_static::initialize(&PANIC_HOOK);

Expand All @@ -266,9 +269,11 @@ pub fn fuzz<F>(closure: F) where F: FnOnce(&[u8]) + std::panic::UnwindSafe {
// the panic hook.
// If so, the fuzzer will be unable to tell different bugs appart and you will
// only be able to find one bug at a time before fixing it to then find a new one.
let did_panic = std::panic::catch_unwind(|| {
// The closure is assumed to be unwind-safe, which might be unsafe. For more info, check the
// [`std::panic::UnwindSafe`] trait.
let did_panic = std::panic::catch_unwind(std::panic::AssertUnwindSafe(|| {
closure(buf);
}).is_err();
})).is_err();

if did_panic {
// hopefully the custom panic hook will be called before and abort the
Expand Down