Skip to content

Commit

Permalink
Merge #10
Browse files Browse the repository at this point in the history
10: Allow more closures r=PaulGrandperrin a=PaulGrandperrin

This PR is based on the work from: 
- @mcginty : #9 
- @g2p : #8  

Co-authored-by: Paul Grandperrin <[email protected]>
Co-authored-by: Jake McGinty <[email protected]>
Co-authored-by: Gabriel <[email protected]>
  • Loading branch information
4 people committed Aug 28, 2018
2 parents cafed52 + 629a0d6 commit 616e357
Show file tree
Hide file tree
Showing 3 changed files with 18 additions and 3 deletions.
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

0 comments on commit 616e357

Please sign in to comment.