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

Generalize fuzz macro #119

Open
Manishearth opened this issue Jun 10, 2017 · 1 comment · May be fixed by rust-fuzz/libfuzzer#33
Open

Generalize fuzz macro #119

Manishearth opened this issue Jun 10, 2017 · 1 comment · May be fixed by rust-fuzz/libfuzzer#33

Comments

@Manishearth
Copy link
Member

Currently a fuzz target looks like

#![no_main]
#[macro_use] extern crate libfuzzer_sys;
extern crate thing;

fuzz_target!(|data: Type| {
    //stuff
});

Ideally, it would instead look like

extern crate thing;

#[macro_use] extern crate arbitrary_macros;

target!(|data: Type| {
    // stuff
});

where the macro introduces the no_main and the libfuzzer_sys.

This means we could use the same script for a quickcheck, or for running with seer

The exact code it expands to can be controlled by a cfg that is a part of the macro expansion. This way we can have cargo-fuzz also do things like cargo fuzz seer name_of_script or cargo fuzz quickcheck name_of_script, which will pass different cfg args to the fuzzer script and do a completely different thing.

Having a common API would be pretty neat, overall. Also makes it easier to be agnostic over the fuzzer.

cc @nagisa @frewsxcv @dwrensha

@killercup
Copy link
Member

killercup commented Apr 28, 2018

@PaulGrandperrin, even after seeing https://github.com/rust-fuzz/libfuzzer-sys/pull/33 and rust-fuzz/afl.rs#137, I don't think this should be closed or at least that we can go one step further. If you don't agree, feel free to close it again.

Is there any reason to not also put the extern crate and fn main stuff into a macro that the other fuzzers might also use to present a truly uniform interface?

Let's compare the code you write for the three fuzzers right now:

/// AFL
extern crate afl;

fn main() {
    // … setup …
    afl::read_stdio_bytes(|data|{
        // … your code …
    });
}
/// honggfuzz
#[macro_use] extern crate honggfuzz;

fn main() {
    // … setup …
    loop {
        fuzz!(|data|{
            // … your code …
        })
    }
}
/// libfuzzer after this https://github.com/rust-fuzz/libfuzzer-sys/pull/33
#[macro_use] extern crate libfuzzer_sys;

fn main() {
    // … setup …
    fuzz!(|data: &[u8]| {
        // … your code …
    });
}

This looks all very similar to me, except for the extern crate and the way you separate your fuzz code from your setup code. In an ideal world, cargo-fuzz and the code in fuzz/ should be agnostic to the actual fuzzer used. Imagine:

#[macro_use] extern crate fuzz;

fuzz!(
    optional_name_if_you_want_it_to_differ_from_the_binary_name,
    setup { /* setup is optional */ },
    |data: Type| { /* actual fuzzer code */ }
);

and invoking it with cargo fuzz run name --fuzzer honggfuzz. This is what the issue description also mentions.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging a pull request may close this issue.

4 participants