Skip to content

Commit 64f5854

Browse files
committed
Support for arbitrary data types
Not efficient[1], but that mostly needs work on the arbitrary crate, as opposed to work on libfuzzer-sys. [1]: fuzzing struggles with e.g. fuzz_target!(|data: String| { if data == "banana" { panic!() } }); and takes quite a while to find an input that fails the check (compared to fuzzing against raw bytes). It seems to me that to take full advantage of fuzzing structured data, one would have to adjust libFuzzer somehow or, perhaps, rewrite libFuzzer in rust having precisely structured fuzzing in mind.
1 parent 36a3928 commit 64f5854

File tree

6 files changed

+46
-9
lines changed

6 files changed

+46
-9
lines changed

.travis.yml

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,5 +12,8 @@ notifications:
1212
email: false
1313
script:
1414
- cd example
15-
- cargo rustc -- -C passes='sancov' -C llvm-args='-sanitizer-coverage-level=3' -Z sanitizer=address
16-
- (! ./target/debug/example)
15+
- cargo rustc --release -- -C passes='sancov' -C llvm-args='-sanitizer-coverage-level=4' -Z sanitizer=address
16+
- (! ./target/release/example -runs=100000)
17+
- cd ../example_arbitrary
18+
- cargo rustc --release -- -C passes='sancov' -C llvm-args='-sanitizer-coverage-level=4' -Z sanitizer=address
19+
- (! ./target/release/example -runs=10000000)

Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ license = "MIT/Apache-2.0/NCSA"
1212
members = ["."]
1313

1414
[dependencies]
15+
arbitrary = "0.1"
1516

1617
[build-dependencies]
1718
gcc = "0.3"

example/src/main.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,8 @@
33
#[macro_use]
44
extern crate libfuzzer_sys;
55

6-
fuzz_target!(|data| {
7-
if data == b"banana" {
6+
fuzz_target!(|data: &[u8]| {
7+
if data == b"banana!" {
88
panic!("success!");
99
}
1010
});

example_arbitrary/Cargo.toml

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
[package]
2+
name = "example"
3+
version = "0.1.0"
4+
authors = ["Simonas Kazlauskas <[email protected]>"]
5+
6+
[workspace]
7+
members = ["."]
8+
9+
[dependencies]
10+
libfuzzer-sys = { path = ".." }
11+
arbitrary = "0.1"

example_arbitrary/src/main.rs

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
#![no_main]
2+
3+
#[macro_use]
4+
extern crate libfuzzer_sys;
5+
6+
fuzz_target!(|data: u16| {
7+
if data == 0xba7 { // ba[nana]
8+
panic!("success!");
9+
}
10+
});

src/lib.rs

Lines changed: 17 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,3 @@
1-
#![feature(process_abort)]
2-
31
extern "C" {
42
#![allow(improper_ctypes)] // we do not actually cross the FFI bound here
53

@@ -23,10 +21,24 @@ macro_rules! fuzz_target {
2321
$body
2422
}
2523
};
26-
(|$bytes:ident: &[u8]| $body:block) => {
24+
(|$data:ident: &[u8]| $body:block) => {
25+
fuzz_target!(|$data| $body);
26+
};
27+
(|$data:ident: $dty: ty| $body:block) => {
28+
extern crate arbitrary;
29+
2730
#[no_mangle]
28-
pub extern fn rust_fuzzer_test_input($bytes: &[u8]) {
31+
pub extern fn rust_fuzzer_test_input(bytes: &[u8]) {
32+
use arbitrary::{Arbitrary, RingBuffer};
33+
34+
let $data: $dty = if let Ok(d) = RingBuffer::new(bytes, bytes.len()).and_then(|mut b|{
35+
Arbitrary::arbitrary(&mut b).map_err(|_| "")
36+
}) {
37+
d
38+
} else {
39+
return
40+
};
2941
$body
3042
}
31-
}
43+
};
3244
}

0 commit comments

Comments
 (0)