cargo-fuzz icon indicating copy to clipboard operation
cargo-fuzz copied to clipboard

Add option to ignore panics

Open Shnatsel opened this issue 5 years ago • 5 comments

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.

Shnatsel avatar May 26 '19 16:05 Shnatsel

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

Shnatsel avatar May 26 '19 16:05 Shnatsel

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

Manishearth avatar May 26 '19 16:05 Manishearth

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.

Shnatsel avatar May 29 '19 20:05 Shnatsel

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

douglas-raillard-arm avatar Jan 05 '24 18:01 douglas-raillard-arm

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
% 

kpcyrd avatar Jan 06 '24 11:01 kpcyrd