Skip to content

Commit 1ccd891

Browse files
committed
Write debug output to RUST_LIBFUZZER_DEBUG_PATH, when set
And then return. This is intended for use by `cargo fuzz` for getting nice info about an `Arbitrary` input that caused a crash.
1 parent a835998 commit 1ccd891

File tree

3 files changed

+35
-1
lines changed

3 files changed

+35
-1
lines changed

ci/script.sh

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,4 +33,9 @@ cargo rustc \
3333
-Cllvm-args=-sanitizer-coverage-prune-blocks=0 \
3434
-Zsanitizer=address
3535
(! $CARGO_TARGET_DIR/release/example_arbitrary -runs=10000000)
36+
RUST_LIBFUZZER_DEBUG_PATH=$(pwd)/debug_output \
37+
$CARGO_TARGET_DIR/release/example_arbitrary \
38+
$(ls ./crash-* | head -n 1)
39+
cat $(pwd)/debug_output
40+
grep -q Rgb $(pwd)/debug_output
3641
popd

example_arbitrary/.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1 +1,2 @@
11
crash-*
2+
debug_output

src/lib.rs

Lines changed: 29 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -118,6 +118,18 @@ macro_rules! fuzz_target {
118118
(|$bytes:ident| $body:block) => {
119119
#[no_mangle]
120120
pub extern "C" fn rust_fuzzer_test_input($bytes: &[u8]) {
121+
// When `RUST_LIBFUZZER_DEBUG_PATH` is set, write the debug
122+
// formatting of the input to that file. This is only intended for
123+
// `cargo fuzz`'s use!
124+
if let Ok(path) = std::env::var("RUST_LIBFUZZER_DEBUG_PATH") {
125+
use std::io::Write;
126+
let mut file = std::fs::File::create(path)
127+
.expect("failed to create `RUST_LIBFUZZER_DEBUG_PATH` file");
128+
writeln!(&mut file, "{:?}", $bytes)
129+
.expect("failed to write to `RUST_LIBFUZZER_DEBUG_PATH` file");
130+
return;
131+
}
132+
121133
$body
122134
}
123135
};
@@ -132,8 +144,24 @@ macro_rules! fuzz_target {
132144
use libfuzzer_sys::arbitrary::{Arbitrary, Unstructured};
133145

134146
let mut u = Unstructured::new(bytes);
147+
let data = <$dty as Arbitrary>::arbitrary_take_rest(u);
148+
149+
// When `RUST_LIBFUZZER_DEBUG_PATH` is set, write the debug
150+
// formatting of the input to that file. This is only intended for
151+
// `cargo fuzz`'s use!
152+
if let Ok(path) = std::env::var("RUST_LIBFUZZER_DEBUG_PATH") {
153+
use std::io::Write;
154+
let mut file = std::fs::File::create(path)
155+
.expect("failed to create `RUST_LIBFUZZER_DEBUG_PATH` file");
156+
(match data {
157+
Ok(data) => writeln!(&mut file, "{:#?}", data),
158+
Err(err) => writeln!(&mut file, "Arbitrary Error: {}", err),
159+
})
160+
.expect("failed to write to `RUST_LIBFUZZER_DEBUG_PATH` file");
161+
return;
162+
}
135163

136-
let $data: $dty = match Arbitrary::arbitrary_take_rest(u) {
164+
let $data = match data {
137165
Ok(d) => d,
138166
Err(_) => return,
139167
};

0 commit comments

Comments
 (0)