cargo-fuzz
cargo-fuzz copied to clipboard
Add option to ignore panics
I'm looking into fuzzing parts of Rust standard library to detect bugs such as CVE-2018-1000810. See also: the fix.
However, this is currently impossible with cargo-fuzz because it passes -Cpanic=abort
during compilation, while for this function panic on overflow is the expected behavior. I need a way to disable that.
In an ideal world I'd like to toggle this behavior persistently for each fuzzing target, but unconditional -Cpanic=abort
makes it impossible. The best way forward that I see is --ignore-panics
flag for cargo fuzz run
I think the panic infrastructure messes with fuzzing somehow so it's disabled for that reason too. You're free to try it and if it works, make a PR with the flag.
The expected thing to do with such cases is to filter the input beforehand
For future reference, I currently have no plans to implement this feature by myself because use of libfuzzer in my project is blocked by #174 anyway.
I was also looking into fuzzing but my only goal is to find hard crashes (segfaults). I know my API can panic in some circumstances, so cargo fuzz stopping on them is not very useful to me.
EDIT: for reference, I'm trying to fuzz a file format parser, so filtering the input is basically impossible
I was wondering if maybe std::panic::catch_unwind
would work for this, but it didn't:
#![no_main]
use libfuzzer_sys::fuzz_target;
fn this_panics(buf: &[u8]) {
if buf.len() > 5 {
panic!("oh no");
}
}
fuzz_target!(|data: &[u8]| {
std::panic::catch_unwind(|| {
this_panics(data);
}).ok();
});
% cargo new fuzz-test
Created binary (application) `fuzz-test` package
% cd fuzz-test
% cargo fuzz init
% cat > fuzz/fuzz_targets/fuzz_target_1.rs
#![no_main]
use libfuzzer_sys::fuzz_target;
fn this_panics(buf: &[u8]) {
if buf.len() > 5 {
panic!("oh no");
}
}
fuzz_target!(|data: &[u8]| {
std::panic::catch_unwind(|| {
this_panics(data);
}).ok();
});
% RUSTC_BOOTSTRAP=1 cargo fuzz run fuzz_target_1 -s none
Updating crates.io index
warning: fuzz-test-fuzz v0.0.0 (/.../fuzz-test/fuzz) ignoring invalid dependency `fuzz-test` which is missing a lib target
Compiling libc v0.2.151
Compiling arbitrary v1.3.2
Compiling once_cell v1.19.0
Compiling jobserver v0.1.27
Compiling cc v1.0.83
Compiling libfuzzer-sys v0.4.7
Compiling fuzz-test-fuzz v0.0.0 (/.../fuzz-test/fuzz)
Finished release [optimized + debuginfo] target(s) in 15.15s
warning: fuzz-test-fuzz v0.0.0 (/.../fuzz-test/fuzz) ignoring invalid dependency `fuzz-test` which is missing a lib target
Finished release [optimized + debuginfo] target(s) in 0.01s
Running `fuzz/target/x86_64-unknown-linux-gnu/release/fuzz_target_1 -artifact_prefix=/.../fuzz-test/fuzz/artifacts/fuzz_target_1/ /.../fuzz-test/fuzz/corpus/fuzz_target_1`
WARNING: Failed to find function "__sanitizer_acquire_crash_state".
WARNING: Failed to find function "__sanitizer_print_stack_trace".
WARNING: Failed to find function "__sanitizer_set_death_callback".
INFO: Running with entropic power schedule (0xFF, 100).
INFO: Seed: 1058425890
INFO: Loaded 1 modules (789 inline 8-bit counters): 789 [0x7ffb2d5cbb0, 0x7ffb2d5cec5),
INFO: Loaded 1 PC tables (789 PCs): 789 [0x7ffb2d5cec8,0x7ffb2d60018),
INFO: 0 files found in /.../fuzz-test/fuzz/corpus/fuzz_target_1
INFO: -max_len is not provided; libFuzzer will not generate inputs larger than 4096 bytes
INFO: A corpus is not provided, starting from an empty corpus
#2 INITED cov: 6 ft: 7 corp: 1/1b exec/s: 0 rss: 27Mb
thread '<unnamed>' panicked at fuzz_targets/fuzz_target_1.rs:7:9:
oh no
note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace
==1224546== ERROR: libFuzzer: deadly signal
NOTE: libFuzzer has rudimentary signal handlers.
Combine libFuzzer with AddressSanitizer or similar for better crash reports.
SUMMARY: libFuzzer: deadly signal
MS: 3 ChangeByte-CMP-InsertByte- DE: "\377\377\377\377"-; base unit: adc83b19e793491b1c6ea0fd8b46cd9f32e592fc
0xff,0xff,0xff,0xff,0x27,0x2b,
\377\377\377\377'+
artifact_prefix='/.../fuzz-test/fuzz/artifacts/fuzz_target_1/'; Test unit written to /.../fuzz-test/fuzz/artifacts/fuzz_target_1/crash-b4b0af687a34ed0e2f21ff234bdd63867e108f74
Base64: /////ycr
────────────────────────────────────────────────────────────────────────────────
Failing input:
fuzz/artifacts/fuzz_target_1/crash-b4b0af687a34ed0e2f21ff234bdd63867e108f74
Output of `std::fmt::Debug`:
[255, 255, 255, 255, 39, 43]
Reproduce with:
cargo fuzz run --sanitizer=none fuzz_target_1 fuzz/artifacts/fuzz_target_1/crash-b4b0af687a34ed0e2f21ff234bdd63867e108f74
Minimize test case with:
cargo fuzz tmin --sanitizer=none fuzz_target_1 fuzz/artifacts/fuzz_target_1/crash-b4b0af687a34ed0e2f21ff234bdd63867e108f74
────────────────────────────────────────────────────────────────────────────────
Error: Fuzz target exited with exit status: 77
%