Macro libfuzzer_sys::fuzz_target
source · macro_rules! fuzz_target { (|$bytes:ident| $body:expr) => { ... }; (|$data:ident: &[u8]| $body:expr) => { ... }; (|$data:ident: $dty:ty| $body:expr) => { ... }; (|$data:ident: $dty:ty| -> $rty:ty $body:block) => { ... }; }
Expand description
Define a fuzz target.
Example
This example takes a &[u8]
slice and attempts to parse it. The parsing
might fail and return an Err
, but it shouldn’t ever panic or segfault.
#![no_main]
use libfuzzer_sys::fuzz_target;
// Note: `|input|` is short for `|input: &[u8]|`.
fuzz_target!(|input| {
let _result: Result<_, _> = my_crate::parse(input);
});
Rejecting Inputs
It may be desirable to reject some inputs, i.e. to not add them to the corpus.
For example, when fuzzing an API consisting of parsing and other logic,
one may want to allow only those inputs into the corpus that parse
successfully. To indicate whether an input should be kept in or rejected
from the corpus, return either Corpus::Keep or Corpus::Reject from your
fuzz target. The default behavior (e.g. if ()
is returned) is to keep the
input in the corpus.
For example:
#![no_main]
use libfuzzer_sys::{Corpus, fuzz_target};
fuzz_target!(|input: String| -> Corpus {
let parts: Vec<&str> = input.splitn(2, '=').collect();
if parts.len() != 2 {
return Corpus::Reject;
}
let key = parts[0];
let value = parts[1];
let _result: Result<_, _> = my_crate::parse(key, value);
Corpus::Keep
});
Arbitrary Input Types
The input is a &[u8]
slice by default, but you can take arbitrary input
types, as long as the type implements the arbitrary
crate’s Arbitrary
trait (which is
also re-exported as libfuzzer_sys::arbitrary::Arbitrary
for convenience).
For example, if you wanted to take an arbitrary RGB color, you could do the following:
#![no_main]
use libfuzzer_sys::{arbitrary::{Arbitrary, Error, Unstructured}, fuzz_target};
#[derive(Debug)]
pub struct Rgb {
r: u8,
g: u8,
b: u8,
}
impl<'a> Arbitrary<'a> for Rgb {
fn arbitrary(raw: &mut Unstructured<'a>) -> Result<Self, Error> {
let mut buf = [0; 3];
raw.fill_buffer(&mut buf)?;
let r = buf[0];
let g = buf[1];
let b = buf[2];
Ok(Rgb { r, g, b })
}
}
// Write a fuzz target that works with RGB colors instead of raw bytes.
fuzz_target!(|color: Rgb| {
my_crate::convert_color(color);
});
You can also enable the arbitrary
crate’s custom derive via this crate’s
"arbitrary-derive"
cargo feature.