1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
extern "C" {
#![allow(improper_ctypes)]
fn rust_fuzzer_test_input(input: &[u8]);
}
#[export_name = "LLVMFuzzerTestOneInput"]
pub fn test_input_wrap(data: *const u8, size: usize) -> i32 {
if ::std::panic::catch_unwind(|| unsafe {
let data_slice = ::std::slice::from_raw_parts(data, size);
rust_fuzzer_test_input(data_slice);
})
.err()
.is_some()
{
::std::process::abort();
}
0
}
#[export_name = "LLVMFuzzerInitialize"]
pub fn initialize(_argc: *const isize, _argv: *const *const *const u8) -> isize {
::std::panic::set_hook(Box::new(|_| {
::std::process::abort();
}));
0
}
#[macro_export]
macro_rules! fuzz_target {
(|$bytes:ident| $body:block) => {
#[no_mangle]
pub extern "C" fn rust_fuzzer_test_input($bytes: &[u8]) {
$body
}
};
(|$data:ident: &[u8]| $body:block) => {
fuzz_target!(|$data| $body);
};
(|$data:ident: $dty: ty| $body:block) => {
extern crate arbitrary;
#[no_mangle]
pub extern "C" fn rust_fuzzer_test_input(bytes: &[u8]) {
use arbitrary::{Arbitrary, RingBuffer};
let $data: $dty = if let Ok(d) = RingBuffer::new(bytes, bytes.len())
.and_then(|mut b| Arbitrary::arbitrary(&mut b).map_err(|_| ""))
{
d
} else {
return;
};
$body
}
};
}