Modular, structure-aware, and feedback-driven fuzzing engine for Rust functions

Overview

Fuzzcheck

CI Docs MIT licensed crates.io

Fuzzcheck is a modular, structure-aware, and feedback-driven fuzzing engine for Rust functions.

Given a function test: (T) -> bool, you can use fuzzcheck to find a value of type T that fails the test or leads to a crash.

The tool fuzzcheck-view is available to visualise the code coverage of each/all test cases generated by fuzzcheck. It is still just a prototype though.

Follow the guide at fuzzcheck.neocities.org to get started or read the documentation on docs.rs.

Setup

Linux or macOS is required. Windows support is planned but I need help with it.

Rust nightly is also required. You can install it with:

rustup toolchain install nightly

While it is not strictly necessary, installing the cargo-fuzzcheck executable will make it easier to run fuzzcheck.

cargo install cargo-fuzzcheck

In your Cargo.toml file, add fuzzcheck as a dev-dependency:

[dev-dependencies]
fuzzcheck = "0.10"

Then, we need a way to serialize values. By default, fuzzcheck uses serde_json for that purpose (but it can be changed). That means our data types should implement serde's traits. In Cargo.toml, add:

[dependencies]
serde = { version = "1.0", features = ["derive"] }

Usage

Below is an example of how to use fuzz test. Note:

  1. every code related to fuzzcheck is conditional on #[cfg(test)] because we don't want to carry the fuzzcheck dependency in normal builds
  2. the #![cfg_attr(test, feature(no_coverage))] is required by fuzzcheck’s procedural macros
  3. the use of derive(fuzzcheck::DefaultMutator) makes a custom type fuzzable
#![cfg_attr(test, feature(no_coverage))]
use serde::{Deserialize, Serialize};

#[cfg_attr(test, derive(fuzzcheck::DefaultMutator))]
#[derive(Clone, Serialize, Deserialize)]
struct SampleStruct<T, U> {
    x: T,
    y: U,
}

#[cfg_attr(test, derive(fuzzcheck::DefaultMutator))]
#[derive(Clone, Serialize, Deserialize)]
enum SampleEnum {
    A(u16),
    B,
    C { x: bool, y: bool },
}

fn should_not_crash(xs: &[SampleStruct<u8, SampleEnum>]) {
    if xs.len() > 3
        && xs[0].x == 100
        && matches!(xs[0].y, SampleEnum::C { x: false, y: true })
        && xs[1].x == 55
        && matches!(xs[1].y, SampleEnum::C { x: true, y: false })
        && xs[2].x == 87
        && matches!(xs[2].y, SampleEnum::C { x: false, y: false })
        && xs[3].x == 24
        && matches!(xs[3].y, SampleEnum::C { x: true, y: true })
    {
        panic!()
    }
}

// fuzz tests reside along your other tests and have the #[test] attribute
#[cfg(test)]
mod tests {
    #[test]
    fn test_function_shouldn_t_crash() {
        let result = fuzzcheck::fuzz_test(super::should_not_crash) // the test function to fuzz
            .default_mutator() // the mutator to generate values of &[SampleStruct<u8, SampleEnum>]
            .serde_serializer() // save the test cases to the file system using serde
            .default_sensor_and_pool() // gather observations using the default sensor (i.e. recording code coverage)
            .arguments_from_cargo_fuzzcheck() // take arguments from the cargo-fuzzcheck command line tool
            .stop_after_first_test_failure(true) // stop the fuzzer as soon as a test failure is found
            .launch();
        assert!(!result.found_test_failure);
    }
}

We can now use cargo-fuzzcheck to launch the test, using Rust nightly:

rustup override set nightly
# the argument is the *exact* path to the test function
cargo fuzzcheck tests::test_function_shouldn_t_crash

This starts a loop that will stop when a failing test has been found. After about ~50ms of fuzz-testing on my machine, the following line is printed:

Failing test case found. Saving at "fuzz/tests::test_function_shouldn_t_crash/artifacts/59886edc1de2dcc1.json"

The file 59886edc1de2dcc1.json contains the JSON-encoded input that failed the test.

[
  {
    "x": 100,
    "y": {
      "C": {
        "x": false,
        "y": true
      }
    }
  },
  {
    "x": 55,
    "y": {
      "C": {
        "x": true,
        "y": false
      }
    }
  },
  ..
]

Minifying failing test inputs

Fuzzcheck can also be used to minify a large input that fails a test. If the failure is recoverable (i.e. it is not a segfault/stack overflow), and the fuzzer is not instructed to stop after the first failure, then the failing test cases will be minified automatically. Otherwise, you can use the minify command.

Let's say you have a file crash.json containing an input that you would like to minify. Launch cargo fuzzcheck <exact name of fuzz test> with the minify command and an --input-file option.

cargo fuzzcheck "tests::test_function_shouldn_t_crash" --command minify --input-file "crash.json"

This will repeatedly launch the fuzzer in “minify” mode and save the artifacts in the folder artifacts/crash.minified. The name of each artifact will be prefixed with the complexity of its input. For example, crash.minified/800--fe958d4f003bd4f5.json has a complexity of 8.00.

You can stop the minifying fuzzer at any point and look for the least complex input in the crash.minified folder.

Alternatives

Other crates with the same goal are quickcheck and proptest. Fuzzcheck can be more powerful than these because it guides the generation of test cases based on feedback generated from running the test function. This feedback is most often code coverage, but can be different.

Another similar crate is cargo-fuzz, often paired with arbitrary. In this case, fuzzcheck has an advantage by being easier to use, more modular, and being more fundamentally structure-aware and thus potentially more efficient.

Previous work on fuzzing engines

As far as I know, evolutionary, coverage-guided fuzzing engines were popularized by American Fuzzy Lop (AFL).
Fuzzcheck is also evolutionary and coverage-guided.

Later on, LLVM released its own fuzzing engine, libFuzzer, which is based on the same ideas as AFL, but it uses Clang’s SanitizerCoverage and is in-process (it lives in the same process as the program being fuzz-tested.
Fuzzcheck is also in-process. It uses rustc’s -Z instrument-coverage option instead of SanitizerCoverage for code coverage instrumentation.

Both AFL and libFuzzer work by manipulating bitstrings (e.g. 1011101011). However, many programs work on structured data, and mutations at the bitstring level may not map to meaningful mutations at the level of the structured data. This problem can be partially addressed by using a compact binary encoding such as protobuf and providing custom mutation functions to libFuzzer that work on the structured data itself. This is a way to perform “structure-aware fuzzing” (talk, tutorial).

An alternative way to deal with structured data is to use generators just like QuickCheck’s Arbitrary trait. And then to “treat the raw byte buffer input provided by the coverage-guided fuzzer as a sequence of random values and implement a “random” number generator around it.” (cited blog post by @fitzgen). The tool cargo-fuzz has recently implemented that approach.

Fuzzcheck is also structure-aware, but unlike previous attempts at structure-aware fuzzing, it doesn't use an intermediary binary encoding such as protobuf nor does it use Quickcheck-like generators. Instead, it directly mutates the typed values in-process. This is better many ways. First, it is faster because there is no need to encode and decode inputs at each iteration. Second, the complexity of the input is given by a user-defined function, which will be more accurate than counting the bytes of the protobuf encoding. Finally, and most importantly, the mutations are faster and more meaningful than those done on protobuf or Arbitrary’s byte buffer-based RNG. A detail that I particularly like about fuzzcheck, and that is possible only because it mutates typed values, is that every mutation is done in-place and is reversable. That means that generating a new test case is super fast, and can often even be done with zero allocations.

As I was developing Fuzzcheck for Swift, a few researchers developed Fuzzchick for Coq (paper). It is a coverage-guided property-based testing tool implemented as an extension to Quickchick. As far as I know, it is the only other tool with the same philosophy as fuzzcheck. The similarity between the names fuzzcheck and Fuzzchick is a coincidence.

LibAFL is another modular fuzzer written in Rust. It was released relatively recently.

Comments
  • Crash while trying to read LLVM covmap

    Crash while trying to read LLVM covmap

    I encountered this crash while trying to run cargo-fuzzcheck.

    This is using the nightly-x86_64-apple-darwin toolchain (rustc 1.56.0-nightly (b70888601 2021-07-28))

    I'm currently experimenting with different rustc versions to see if that makes a difference.

    I'm using the latest version of both fuzzcheck and cargo-fuzzcheck (0.7.0)

    The command I'm using is cargo fuzzcheck leaderboard::test::fuzz_id_encoding fuzz --artifacts fuzz/artifacts (leaderboard::test::fuzz_id_encoding is the path to the test)

    running 1 test
    test leaderboard::test::fuzz_id_encoding ... thread 'main' panicked at 'assertion failed: `(left == right)`
      left: `156`,
     right: `0`', /Users/teymouraldridge/.cargo/registry/src/github.com-1ecc6299db9ec823/fuzzcheck-0.7.0/src/code_coverage_sensor/llvm_coverage.rs:306:5
    stack backtrace:
       0:        0x1031b3df4 - std::backtrace_rs::backtrace::libunwind::trace::h32ef383823110ea5
                                   at /rustc/b70888601af92f6cdc0364abab3446e418b91d36/library/std/src/../../backtrace/src/backtrace/libunwind.rs:90:5
       1:        0x1031b3df4 - std::backtrace_rs::backtrace::trace_unsynchronized::h39cafb439612ba84
                                   at /rustc/b70888601af92f6cdc0364abab3446e418b91d36/library/std/src/../../backtrace/src/backtrace/mod.rs:66:5
       2:        0x1031b3df4 - std::sys_common::backtrace::_print_fmt::h57709926472a5d5c
                                   at /rustc/b70888601af92f6cdc0364abab3446e418b91d36/library/std/src/sys_common/backtrace.rs:67:5
       3:        0x1031b3df4 - <std::sys_common::backtrace::_print::DisplayBacktrace as core::fmt::Display>::fmt::hbf0f7aeb2a01393a
                                   at /rustc/b70888601af92f6cdc0364abab3446e418b91d36/library/std/src/sys_common/backtrace.rs:46:22
       4:        0x1031d7ffc - core::fmt::write::h8160330c41daaf61
                                   at /rustc/b70888601af92f6cdc0364abab3446e418b91d36/library/core/src/fmt/mod.rs:1115:17
       5:        0x1031ab8da - std::io::Write::write_fmt::haa5623a2a8d2ec9f
                                   at /rustc/b70888601af92f6cdc0364abab3446e418b91d36/library/std/src/io/mod.rs:1665:15
       6:        0x1031b620f - std::sys_common::backtrace::_print::ha01b9c824fd26115
                                   at /rustc/b70888601af92f6cdc0364abab3446e418b91d36/library/std/src/sys_common/backtrace.rs:49:5
       7:        0x1031b620f - std::sys_common::backtrace::print::hd6de520bd6e67ce7
                                   at /rustc/b70888601af92f6cdc0364abab3446e418b91d36/library/std/src/sys_common/backtrace.rs:36:9
       8:        0x1031b620f - std::panicking::default_hook::{{closure}}::h5fe994d86d862da0
                                   at /rustc/b70888601af92f6cdc0364abab3446e418b91d36/library/std/src/panicking.rs:208:50
       9:        0x1031b5d0d - std::panicking::default_hook::hba89cfe1e23145fb
                                   at /rustc/b70888601af92f6cdc0364abab3446e418b91d36/library/std/src/panicking.rs:225:9
      10:        0x1031b6910 - std::panicking::rust_panic_with_hook::h674e3a191f056728
                                   at /rustc/b70888601af92f6cdc0364abab3446e418b91d36/library/std/src/panicking.rs:622:17
      11:        0x1031b63b5 - std::panicking::begin_panic_handler::{{closure}}::hc97521b9fa6c7ab0
                                   at /rustc/b70888601af92f6cdc0364abab3446e418b91d36/library/std/src/panicking.rs:519:13
      12:        0x1031b4298 - std::sys_common::backtrace::__rust_end_short_backtrace::h9a967faa138ad029
                                   at /rustc/b70888601af92f6cdc0364abab3446e418b91d36/library/std/src/sys_common/backtrace.rs:141:18
      13:        0x1031b631a - rust_begin_unwind
                                   at /rustc/b70888601af92f6cdc0364abab3446e418b91d36/library/std/src/panicking.rs:515:5
      14:        0x10321e58f - core::panicking::panic_fmt::h2e3306ce37bd7247
                                   at /rustc/b70888601af92f6cdc0364abab3446e418b91d36/library/core/src/panicking.rs:92:14
      15:        0x1031d5697 - core::panicking::assert_failed_inner::h4e794867b3d5f849
                                   at /rustc/b70888601af92f6cdc0364abab3446e418b91d36/library/core/src/panicking.rs:160:17
      16:        0x1031f090e - core[1037ddd5376118b]::panicking::assert_failed::<usize, usize>
      17:        0x102a4abed - fuzzcheck[8eebe5071d6b1a76]::code_coverage_sensor::llvm_coverage::read_covmap
      18:        0x1028c8dde - <fuzzcheck[8eebe5071d6b1a76]::code_coverage_sensor::CodeCoverageSensor>::new::<<fuzzcheck[8eebe5071d6b1a76]::builder::FuzzerBuilder4<[i32], main[4da33c02eb1296a4]::leaderboard::test::predicate, fuzzcheck[8eebe5071d6b1a76]::mutators::vector::VecMutator<i32, fuzzcheck[8eebe5071d6b1a76]::mutators::integer::I32Mutator>, alloc[7bd5eaea06473e33]::vec::Vec<i32>, fuzzcheck[8eebe5071d6b1a76]::serializers::serde_serializer::SerdeSerializer<alloc[7bd5eaea06473e33]::vec::Vec<i32>>>>::observe_only_files_from_current_dir::{closure#0}, <fuzzcheck[8eebe5071d6b1a76]::builder::FuzzerBuilder4<[i32], main[4da33c02eb1296a4]::leaderboard::test::predicate, fuzzcheck[8eebe5071d6b1a76]::mutators::vector::VecMutator<i32, fuzzcheck[8eebe5071d6b1a76]::mutators::integer::I32Mutator>, alloc[7bd5eaea06473e33]::vec::Vec<i32>, fuzzcheck[8eebe5071d6b1a76]::serializers::serde_serializer::SerdeSerializer<alloc[7bd5eaea06473e33]::vec::Vec<i32>>>>::observe_only_files_from_current_dir::{closure#1}>
      19:        0x10268ff3c - fuzzcheck[8eebe5071d6b1a76]::fuzzer::launch::<alloc[7bd5eaea06473e33]::vec::Vec<i32>, [i32], main[4da33c02eb1296a4]::leaderboard::test::predicate, fuzzcheck[8eebe5071d6b1a76]::mutators::vector::VecMutator<i32, fuzzcheck[8eebe5071d6b1a76]::mutators::integer::I32Mutator>, fuzzcheck[8eebe5071d6b1a76]::serializers::serde_serializer::SerdeSerializer<alloc[7bd5eaea06473e33]::vec::Vec<i32>>, <fuzzcheck[8eebe5071d6b1a76]::builder::FuzzerBuilder4<[i32], main[4da33c02eb1296a4]::leaderboard::test::predicate, fuzzcheck[8eebe5071d6b1a76]::mutators::vector::VecMutator<i32, fuzzcheck[8eebe5071d6b1a76]::mutators::integer::I32Mutator>, alloc[7bd5eaea06473e33]::vec::Vec<i32>, fuzzcheck[8eebe5071d6b1a76]::serializers::serde_serializer::SerdeSerializer<alloc[7bd5eaea06473e33]::vec::Vec<i32>>>>::observe_only_files_from_current_dir::{closure#0}, <fuzzcheck[8eebe5071d6b1a76]::builder::FuzzerBuilder4<[i32], main[4da33c02eb1296a4]::leaderboard::test::predicate, fuzzcheck[8eebe5071d6b1a76]::mutators::vector::VecMutator<i32, fuzzcheck[8eebe5071d6b1a76]::mutators::integer::I32Mutator>, alloc[7bd5eaea06473e33]::vec::Vec<i32>, fuzzcheck[8eebe5071d6b1a76]::serializers::serde_serializer::SerdeSerializer<alloc[7bd5eaea06473e33]::vec::Vec<i32>>>>::observe_only_files_from_current_dir::{closure#1}>
      20:        0x1026eaba5 - <fuzzcheck[8eebe5071d6b1a76]::builder::FuzzerBuilder5<[i32], main[4da33c02eb1296a4]::leaderboard::test::predicate, fuzzcheck[8eebe5071d6b1a76]::mutators::vector::VecMutator<i32, fuzzcheck[8eebe5071d6b1a76]::mutators::integer::I32Mutator>, alloc[7bd5eaea06473e33]::vec::Vec<i32>, fuzzcheck[8eebe5071d6b1a76]::serializers::serde_serializer::SerdeSerializer<alloc[7bd5eaea06473e33]::vec::Vec<i32>>, <fuzzcheck[8eebe5071d6b1a76]::builder::FuzzerBuilder4<[i32], main[4da33c02eb1296a4]::leaderboard::test::predicate, fuzzcheck[8eebe5071d6b1a76]::mutators::vector::VecMutator<i32, fuzzcheck[8eebe5071d6b1a76]::mutators::integer::I32Mutator>, alloc[7bd5eaea06473e33]::vec::Vec<i32>, fuzzcheck[8eebe5071d6b1a76]::serializers::serde_serializer::SerdeSerializer<alloc[7bd5eaea06473e33]::vec::Vec<i32>>>>::observe_only_files_from_current_dir::{closure#0}, <fuzzcheck[8eebe5071d6b1a76]::builder::FuzzerBuilder4<[i32], main[4da33c02eb1296a4]::leaderboard::test::predicate, fuzzcheck[8eebe5071d6b1a76]::mutators::vector::VecMutator<i32, fuzzcheck[8eebe5071d6b1a76]::mutators::integer::I32Mutator>, alloc[7bd5eaea06473e33]::vec::Vec<i32>, fuzzcheck[8eebe5071d6b1a76]::serializers::serde_serializer::SerdeSerializer<alloc[7bd5eaea06473e33]::vec::Vec<i32>>>>::observe_only_files_from_current_dir::{closure#1}>>::launch
      21:        0x1027555a9 - main[4da33c02eb1296a4]::leaderboard::test::fuzz_id_encoding
      22:        0x102a39cba - core::ops::function::FnOnce::call_once::h864fb8cb65c82ad0
                                   at /rustc/b70888601af92f6cdc0364abab3446e418b91d36/library/core/src/ops/function.rs:227:5
      23:        0x102a39cba - test::__rust_begin_short_backtrace::h7ec90dbafd078692
                                   at /rustc/b70888601af92f6cdc0364abab3446e418b91d36/library/test/src/lib.rs:578:5
      24:        0x102a38974 - <alloc::boxed::Box<F,A> as core::ops::function::FnOnce<Args>>::call_once::h22c35b1fd1591729
                                   at /rustc/b70888601af92f6cdc0364abab3446e418b91d36/library/alloc/src/boxed.rs:1572:9
      25:        0x102a38974 - <std::panic::AssertUnwindSafe<F> as core::ops::function::FnOnce<()>>::call_once::he01aa01c6784e37c
                                   at /rustc/b70888601af92f6cdc0364abab3446e418b91d36/library/std/src/panic.rs:347:9
      26:        0x102a38974 - std::panicking::try::do_call::hc677fc05d38b16ff
                                   at /rustc/b70888601af92f6cdc0364abab3446e418b91d36/library/std/src/panicking.rs:401:40
      27:        0x102a38974 - std::panicking::try::h506c53c09d46da41
                                   at /rustc/b70888601af92f6cdc0364abab3446e418b91d36/library/std/src/panicking.rs:365:19
      28:        0x102a38974 - std::panic::catch_unwind::h9a8b52d6ea7a527e
                                   at /rustc/b70888601af92f6cdc0364abab3446e418b91d36/library/std/src/panic.rs:434:14
      29:        0x102a38974 - test::run_test_in_process::hcd24ff6bb028ff0a
                                   at /rustc/b70888601af92f6cdc0364abab3446e418b91d36/library/test/src/lib.rs:601:18
      30:        0x102a38974 - test::run_test::run_test_inner::{{closure}}::hf60c537148a26f88
                                   at /rustc/b70888601af92f6cdc0364abab3446e418b91d36/library/test/src/lib.rs:493:39
      31:        0x102a37e2d - test::run_test::run_test_inner::h0aa267bb56c93a74
                                   at /rustc/b70888601af92f6cdc0364abab3446e418b91d36/library/test/src/lib.rs:531:13
      32:        0x102a36c1b - test::run_test::hbe8950e7a5e1d1f2
                                   at /rustc/b70888601af92f6cdc0364abab3446e418b91d36/library/test/src/lib.rs:565:28
      33:        0x102a31bc7 - test::run_tests::ha378b857ae47dc9b
                                   at /rustc/b70888601af92f6cdc0364abab3446e418b91d36/library/test/src/lib.rs:306:17
      34:        0x102a1a997 - test::console::run_tests_console::h2b48bcd5822b3fee
                                   at /rustc/b70888601af92f6cdc0364abab3446e418b91d36/library/test/src/console.rs:290:5
      35:        0x102a2fdd5 - test::test_main::hff95eeeba4a6e4b1
                                   at /rustc/b70888601af92f6cdc0364abab3446e418b91d36/library/test/src/lib.rs:123:15
      36:        0x102a30f5f - test::test_main_static::h6e9cc4a43b2aa36a
                                   at /rustc/b70888601af92f6cdc0364abab3446e418b91d36/library/test/src/lib.rs:142:5
      37:        0x10288a22a - std[4656eb4d6ec895b4]::sys_common::backtrace::__rust_begin_short_backtrace::<fn(), ()>
      38:        0x10258d39c - std[4656eb4d6ec895b4]::rt::lang_start::<()>::{closure#0}
      39:        0x1031b6e39 - core::ops::function::impls::<impl core::ops::function::FnOnce<A> for &F>::call_once::he18e274b8ec42070
                                   at /rustc/b70888601af92f6cdc0364abab3446e418b91d36/library/core/src/ops/function.rs:259:13
      40:        0x1031b6e39 - std::panicking::try::do_call::hea026a8f5852112e
                                   at /rustc/b70888601af92f6cdc0364abab3446e418b91d36/library/std/src/panicking.rs:401:40
      41:        0x1031b6e39 - std::panicking::try::h5a1bca372ac4c528
                                   at /rustc/b70888601af92f6cdc0364abab3446e418b91d36/library/std/src/panicking.rs:365:19
      42:        0x1031b6e39 - std::panic::catch_unwind::h4245da8e2d8cbf9a
                                   at /rustc/b70888601af92f6cdc0364abab3446e418b91d36/library/std/src/panic.rs:434:14
      43:        0x1031b6e39 - std::rt::lang_start_internal::{{closure}}::h64dd899fdea61a58
                                   at /rustc/b70888601af92f6cdc0364abab3446e418b91d36/library/std/src/rt.rs:45:48
      44:        0x1031b6e39 - std::panicking::try::do_call::h25d01982e49ebd9a
                                   at /rustc/b70888601af92f6cdc0364abab3446e418b91d36/library/std/src/panicking.rs:401:40
      45:        0x1031b6e39 - std::panicking::try::hb40c0d004f245d35
                                   at /rustc/b70888601af92f6cdc0364abab3446e418b91d36/library/std/src/panicking.rs:365:19
      46:        0x1031b6e39 - std::panic::catch_unwind::hc4bddc94710aa7ee
                                   at /rustc/b70888601af92f6cdc0364abab3446e418b91d36/library/std/src/panic.rs:434:14
      47:        0x1031b6e39 - std::rt::lang_start_internal::hdfe6c30fb8c47cc9
                                   at /rustc/b70888601af92f6cdc0364abab3446e418b91d36/library/std/src/rt.rs:45:20
      48:        0x10266a639 - _main
    FAILED
    
    failures:
    
    failures:
        leaderboard::test::fuzz_id_encoding
    
    opened by teymour-aldridge 12
  • fix out-of-bounds access bug

    fix out-of-bounds access bug

    Unsafe access to the first vector element when the vector was empty was causing a segmentation fault when using fuzzcheck. This patch fixes it.

    Thread 3.1 "action_fuzz-b00" received signal SIGSEGV, Segmentation fault.
    
    [Switching to Thread 0x7ffff7a453c0 (LWP 574366)]
    0x0000555555bb1c7c in <fuzzcheck::code_coverage_sensor::CodeCoverageSensor as fuzzcheck::traits::Sensor>::iterate_over_observations ()
    (gdb) bt
    #0  0x0000555555bb1c7c in <fuzzcheck::code_coverage_sensor::CodeCoverageSensor as fuzzcheck::traits::Sensor>::iterate_over_observations ()
    #1  0x00005555557d487a in <fuzzcheck::sensors_and_pools::and_sensor_and_pool::AndPool<fuzzcheck::sensors_and_pools::simplest_to_activate_counter_pool::SimplestToActivateCounterPool, fuzzcheck::sensors_and_pools::and_sensor_and_pool::AndPool<fuzzcheck::sensors_and_pools::and_sensor_and_pool::AndPool<fuzzcheck::sensors_and_pools::most_n_diverse_pool::MostNDiversePool, fuzzcheck::sensors_and_pools::optimise_aggregate_stat_pool::OptimiseAggregateStatPool<fuzzcheck::sensors_and_pools::optimise_aggregate_stat_pool::NumberOfActivatedCounters>>, fuzzcheck::sensors_and_pools::and_sensor_and_pool::AndPool<fuzzcheck::sensors_and_pools::maximise_counter_value_pool::MaximiseCounterValuePool, fuzzcheck::sensors_and_pools::optimise_aggregate_stat_pool::OptimiseAggregateStatPool<fuzzcheck::sensors_and_pools::optimise_aggregate_stat_pool::SumOfCounterValues>>>> as fuzzcheck::traits::CompatibleWithSensor<fuzzcheck::code_coverage_sensor::CodeCoverageSensor>>::process ()
    
    opened by dkuehr 8
  • Error minifying an input

    Error minifying an input

    I found a failing test case, however, trying to minify it fails:

    error: linking with `cc` failed: exit status: 1
    
      = note: Undefined symbols for architecture x86_64:
                "___llvm_profile_runtime", referenced from:
                    ___llvm_profile_runtime_user in fuzz_parser-10a0a12e83348750.fuzz_parser.6cb7562a-cgu.0.rcgu.o
                   (maybe you meant: ___llvm_profile_runtime_user)
              ld: symbol(s) not found for architecture x86_64
              clang: error: linker command failed with exit code 1 (use -v to see invocation)
    

    I'm on MacOS Catalina, x86_64.

    opened by teymour-aldridge 7
  • Recurrence of recursive mutator bug

    Recurrence of recursive mutator bug

    Unfortunately I think that #31 is still here: I tried writing a recursive JSON generator recently, but this crashes pretty quickly after being launched. I thought this might be because I modify the fuzzcheck generated types before converting them to the serde_json::Value enum (stripping invalid characters from the strings), but I removed that code and it didn't seem to fix the problem. The code is at https://git.sr.ht/~teymour/fuzzcheck_generators/tree/ (in fuzzcheck_serde_json_generator), and I get this error output (using the latest commit in the fuzzcheck repository)

    thread 'main' panicked at 'The mutator used by the fuzz test does not evaluate the complexity of the test cases consistently.
                        This is a bug in the implementation of fuzzcheck::mutators::map::MapMutator<fuzzcheck_serde_json_generator::InternalJsonValue, serde_json::value::Value, fuzzcheck::mutators::recursive::RecursiveMutator<fuzzcheck_serde_json_generator::InternalJsonValueMutator>, fuzzcheck_serde_json_generator::json_value_mutator::{{closure}}, fuzzcheck_serde_json_generator::json_value_mutator::{{closure}}, fuzzcheck_serde_json_generator::json_value_mutator::{{closure}}>
                        =============
                        
                        {"":[]}
    
                        =============
                        ', /Users/teymour/.cargo/git/checkouts/fuzzcheck-rs-531eb3f95f61a5dd/2bfa9f0/fuzzcheck/src/fuzzer.rs:445:17
    note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace
    FAILED
    
    opened by teymour-aldridge 6
  • Avoid constructing a specific variant of an enum when using `DefaultMutator`

    Avoid constructing a specific variant of an enum when using `DefaultMutator`

    Is it possible to instruct Fuzzcheck not to use a specific variant of an enum?

    e.g.

    #[derive(DefaultMutator)]
    pub enum X {
      // fuzzcheck should construct this one
      SimpleType(String),
      // fuzzcheck should also construct this one
      AlsoSimpleType(i32),
      // fuzzcheck should not construct this one
      DoNotConstruct(HashMap<String, Vec<(usize, i32, String)>>
    }
    

    If it isn't, I'd be happy to implement this.

    opened by teymour-aldridge 6
  • Errors running fuzzcheck

    Errors running fuzzcheck

    I hope you're well :)

    (relevant code at the bottom of this issue)

    I'm trying to test a small parser with fuzzcheck, and I am running into a couple of errors.

    The first error I found was (everything running on MacOS Catalina, x86_64):

    teymouraldridge@Teymours-MBP tmp-XVrRgj % cargo +nightly fuzzcheck fuzz::test_fuzz_parser fuzz
    error: failed to run `rustc` to learn about target-specific information
    
    Caused by:
      process didn't exit successfully: `rustc - --crate-name ___ --print=file-names -Zinstrument-coverage=except-unused-functions -Zno-profiler-runtime --cfg fuzzing --target x86_64-apple-darwin --crate-type bin --crate-type rlib --crate-type dylib --crate-type cdylib --crate-type staticlib --crate-type proc-macro --print=sysroot --print=cfg` (exit status: 1)
      --- stderr
      error: unknown debugging option: `no-profiler-runtime`
    

    I updated everything (rust toolchain – so running the latest nightly – and fuzzcheck) and that issue went away (yay!) but instead this issue appears:

    teymouraldridge@Teymours-MBP tmp-XVrRgj % cargo +nightly fuzzcheck fuzz::test_fuzz_parser fuzz
    error: no library targets found in package `tmp-xvrrgj`
    

    My code is as follows:

    use std::mem;
    
    fn main() {}
    
    fn exec(mut instruction: String) -> Vec<u8> {
        let shuffles = Shuffles::parse(&mut instruction);
        let mut vec: Vec<u8> = vec![1, 2, 3, 4, 5, 6, 7, 8];
        shuffles.execute(&mut vec)
    }
    
    /// Formal grammar:
    /// ```
    /// instructions ::= (instruction)+
    /// instruction ::= 'b'
    ///                 'i'
    ///                 'o'
    ///                 '(' + instruction+ + ')'
    ///                 '0'..='9' + instruction
    /// ```
    
    #[derive(Debug)]
    struct Shuffles(Vec<Shuffle>);
    
    impl Shuffles {
        fn parse(input: &mut String) -> Self {
            let mut output = vec![];
    
            loop {
                if input.starts_with(')') || input.is_empty() {
                    return Self(output);
                }
                output.push(Shuffle::parse(input))
            }
        }
    
        fn execute(&self, sequence: &mut Vec<u8>) -> Vec<u8> {
            for shuffle in &self.0 {
                shuffle.execute(sequence);
            }
            sequence.to_vec()
        }
    }
    
    #[derive(Debug)]
    enum Shuffle {
        Break,
        InRiffle,
        OutRiffle,
        Group(Shuffles),
        Repeat(u8, Box<Shuffle>),
    }
    
    impl Shuffle {
        fn execute(&self, sequence: &mut Vec<u8>) {
            match self {
                Shuffle::Break => {
                    let character = sequence.remove(0);
                    sequence.push(character);
                }
                Shuffle::InRiffle => {
                    let mut new = vec![];
                    let top_half = &sequence[0..sequence.len() / 2];
                    let bottom_half = &sequence[sequence.len() / 2..];
                    assert_eq!(top_half.len(), bottom_half.len());
                    for (top, bottom) in top_half.into_iter().zip(bottom_half) {
                        new.push(*bottom);
                        new.push(*top);
                    }
                    mem::swap(&mut new, sequence);
                }
                Shuffle::OutRiffle => {
                    let mut new = vec![];
                    let top_half = &sequence[0..sequence.len() / 2];
                    let bottom_half = &sequence[sequence.len() / 2..];
                    assert_eq!(top_half.len(), bottom_half.len());
                    for (top, bottom) in top_half.into_iter().zip(bottom_half) {
                        new.push(*top);
                        new.push(*bottom);
                    }
                    mem::swap(&mut new, sequence);
                }
                Shuffle::Group(shuffles) => {
                    shuffles.execute(sequence);
                }
                Shuffle::Repeat(n, shuffle) => {
                    for _ in 0..*n {
                        shuffle.execute(sequence)
                    }
                }
            }
        }
    
        fn parse(input: &mut String) -> Self {
            let character = input.remove(0);
            match character {
                'b' => Shuffle::Break,
                'i' => Shuffle::InRiffle,
                'o' => Shuffle::OutRiffle,
                '(' => {
                    let shuffles = Shuffles::parse(input);
                    assert_eq!(input.remove(0), ')');
                    Shuffle::Group(shuffles)
                }
                '0'..='9' => {
                    let mut string = String::from(character);
                    loop {
                        let next = input.chars().next().unwrap();
                        match next {
                            '1'..='9' => {
                                string.push(next);
                                input.remove(0);
                            }
                            _ => {
                                break;
                            }
                        }
                    }
                    let n = string.parse::<u8>().unwrap();
                    let shuffle = Shuffle::parse(input);
                    Shuffle::Repeat(n, Box::new(shuffle))
                }
                _ => panic!(),
            }
        }
    }
    
    #[cfg(test)]
    mod fuzz {
        use fuzzcheck::{
            alternation, concatenation, literal, mutators::grammar::grammar_based_string_mutator,
            recurse, recursive, repetition, FuzzerBuilder, SerdeSerializer,
        };
    
        use crate::Shuffles;
    
        #[test]
        fn test_fuzz_parser() {
            let grammar = repetition! {
                recursive! {
                    g in alternation! {
                        literal!('b'),
                        literal!('i'),
                        literal!('o'),
                        concatenation! {
                            literal!('('),
                            recurse!(g),
                            literal!(')')
                        },
                        concatenation! {
                            repetition!(literal!('0'..='9'), 0..1000),
                            recurse!(g)
                        }
                    }
                },
                0..1000
            };
    
            fn test(input: &String) {
                Shuffles::parse(&mut input.clone());
            }
    
            FuzzerBuilder::test(test)
                .mutator(grammar_based_string_mutator(grammar))
                .serializer(SerdeSerializer::default())
                .arguments_from_cargo_fuzzcheck()
                .observe_only_files_from_current_dir()
                .launch()
        }
    }
    
    opened by teymour-aldridge 6
  • Using `#[field_mutator(...)]` attribute with `DefaultMutator` derive macro.

    Using `#[field_mutator(...)]` attribute with `DefaultMutator` derive macro.

    At the moment you can only use #[field_mutator(...)] with make_mutator!(...) macro.

    Is it possible to allow that attribute for DefaultMutator macro as well to avoid duplicate struct definitions?

    opened by binier 6
  • Allow specific enum variants to be avoided.

    Allow specific enum variants to be avoided.

    This adds an attribute called #[ignore_variant], usable on enums which instructs Fuzzcheck to not construct that variant of the enumeration.

    I haven't yet solved this for generic types.

    opened by teymour-aldridge 5
  • Error

    Error "the mutator used by the fuzz test does not evaluate the complexity of the test cases consistently"

    I encountered this error, and I think it might be a bug in fuzzcheck because I have not implemented any mutators myself (I've only used Fuzzcheck's macros).

    Sorry for the lack of specificity, I'm not really sure about how fuzzcheck's internals work.

    The code in question can be found at these two URLs:

    • https://github.com/bailion/compiler/blob/2b94c2461e91c45724657eaa5e2716b2260858b8/tests/generator/src/lib.rs
    • https://github.com/bailion/compiler/blob/2b94c2461e91c45724657eaa5e2716b2260858b8/tests/fuzzer/src/lib.rs
    opened by teymour-aldridge 4
  • AddressSanitizer complains when stopping fuzzer w/ CTRL+C

    AddressSanitizer complains when stopping fuzzer w/ CTRL+C

    When canceling a running fuzzer with CTRL+C, I get a big ASAN dump regardless of the fuzzing target. The repro command below uses the usage_tests crate, but any test function will do, even an empty one. I haven't spent any time debugging whether this is a real issue or just some ASAN false positive. Unfortunately I'm not getting symbols from AddressSanitizer on where the issue might be : (

    ~/dev/fuzzcheck/usage_tests/basic_crate$ RUST_BACKTRACE=1 cargo +nightly-2022-07-21 fuzzcheck --address-sanitizer tests::fuzz
    
        Finished release [optimized] target(s) in 12.65s
         Running unittests src/lib.rs (target/fuzzcheck/x86_64-unknown-linux-gnu/release/deps/basic_crate-355b4a7b4d1de335)
    
    running 1 test
    test tests::fuzz ... 0ms  START
    29ms  1 simplest_cov(0 cov: 0/46 cplx: 0.00) diverse_cov_20(0) max_each_cov_hits(0 sum: 0) diverse_cov_1(0) max_total_cov_hits(0) iter/s 38461
    30ms  2 simplest_cov(1 cov: 6/46 cplx: 25.00) diverse_cov_20(6) max_each_cov_hits(1 sum: 16) diverse_cov_1(6) max_total_cov_hits(16) iter/s 4192
    30ms  3 simplest_cov(2 cov: 7/46 cplx: 24.00) diverse_cov_20(7) max_each_cov_hits(2 sum: 22) diverse_cov_1(6) max_total_cov_hits(16) iter/s 3911
    34ms  FINISHED READING CORPUS
    35ms  PULSE 292 simplest_cov(2 cov: 7/46 cplx: 24.00) diverse_cov_20(7) max_each_cov_hits(2 sum: 22) diverse_cov_1(6) max_total_cov_hits(16) iter/s 570312
    36ms  PULSE 584 simplest_cov(2 cov: 7/46 cplx: 24.00) diverse_cov_20(7) max_each_cov_hits(2 sum: 22) diverse_cov_1(6) max_total_cov_hits(16) iter/s 422270
    37ms  PULSE 1168 simplest_cov(2 cov: 7/46 cplx: 24.00) diverse_cov_20(7) max_each_cov_hits(2 sum: 22) diverse_cov_1(6) max_total_cov_hits(16) iter/s 387267
    41ms  PULSE 2336 simplest_cov(2 cov: 7/46 cplx: 24.00) diverse_cov_20(7) max_each_cov_hits(2 sum: 22) diverse_cov_1(6) max_total_cov_hits(16) iter/s 343832
    49ms  PULSE 4672 simplest_cov(2 cov: 7/46 cplx: 24.00) diverse_cov_20(7) max_each_cov_hits(2 sum: 22) diverse_cov_1(6) max_total_cov_hits(16) iter/s 326348
    
    ^C
    
    ~/dev/fuzzcheck/usage_tests/basic_crate$ =================================================================
    ==428240==ERROR: AddressSanitizer: heap-buffer-overflow on address 0x625000013fa0 at pc 0x55c662d3d0c2 bp 0x625000013f80 sp 0x625000013750
    WRITE of size 16 at 0x625000013fa0 thread T0
        #0 0x55c662d3d0c1  (~/dev/fuzzcheck/usage_tests/basic_crate/target/fuzzcheck/x86_64-unknown-linux-gnu/release/deps/basic_crate-355b4a7b4d1de335+0x1290c1) (BuildId: faf06c4db8d903caa5edfc5b0ddaf8fc28b78ab2)
        #1 0x55c662ff7ab7  (~/dev/fuzzcheck/usage_tests/basic_crate/target/fuzzcheck/x86_64-unknown-linux-gnu/release/deps/basic_crate-355b4a7b4d1de335+0x3e3ab7) (BuildId: faf06c4db8d903caa5edfc5b0ddaf8fc28b78ab2)
        #2 0x55c662f46c98  (~/dev/fuzzcheck/usage_tests/basic_crate/target/fuzzcheck/x86_64-unknown-linux-gnu/release/deps/basic_crate-355b4a7b4d1de335+0x332c98) (BuildId: faf06c4db8d903caa5edfc5b0ddaf8fc28b78ab2)
        #3 0x55c662e441b6  (~/dev/fuzzcheck/usage_tests/basic_crate/target/fuzzcheck/x86_64-unknown-linux-gnu/release/deps/basic_crate-355b4a7b4d1de335+0x2301b6) (BuildId: faf06c4db8d903caa5edfc5b0ddaf8fc28b78ab2)
        #4 0x55c662e20f56  (~/dev/fuzzcheck/usage_tests/basic_crate/target/fuzzcheck/x86_64-unknown-linux-gnu/release/deps/basic_crate-355b4a7b4d1de335+0x20cf56) (BuildId: faf06c4db8d903caa5edfc5b0ddaf8fc28b78ab2)
        #5 0x55c662f1e3b4  (~/dev/fuzzcheck/usage_tests/basic_crate/target/fuzzcheck/x86_64-unknown-linux-gnu/release/deps/basic_crate-355b4a7b4d1de335+0x30a3b4) (BuildId: faf06c4db8d903caa5edfc5b0ddaf8fc28b78ab2)
        #6 0x55c662f0b6de  (~/dev/fuzzcheck/usage_tests/basic_crate/target/fuzzcheck/x86_64-unknown-linux-gnu/release/deps/basic_crate-355b4a7b4d1de335+0x2f76de) (BuildId: faf06c4db8d903caa5edfc5b0ddaf8fc28b78ab2)
        #7 0x7f4d5eee651f  (/lib/x86_64-linux-gnu/libc.so.6+0x4251f) (BuildId: 89c3cb85f9e55046776471fed05ec441581d1969)
        #8 0x55c662d8d419  (~/dev/fuzzcheck/usage_tests/basic_crate/target/fuzzcheck/x86_64-unknown-linux-gnu/release/deps/basic_crate-355b4a7b4d1de335+0x179419) (BuildId: faf06c4db8d903caa5edfc5b0ddaf8fc28b78ab2)
        #9 0x55c662d8d30d  (~/dev/fuzzcheck/usage_tests/basic_crate/target/fuzzcheck/x86_64-unknown-linux-gnu/release/deps/basic_crate-355b4a7b4d1de335+0x17930d) (BuildId: faf06c4db8d903caa5edfc5b0ddaf8fc28b78ab2)
        #10 0x55c662dd430e  (~/dev/fuzzcheck/usage_tests/basic_crate/target/fuzzcheck/x86_64-unknown-linux-gnu/release/deps/basic_crate-355b4a7b4d1de335+0x1c030e) (BuildId: faf06c4db8d903caa5edfc5b0ddaf8fc28b78ab2)
        #11 0x55c662e4a668  (~/dev/fuzzcheck/usage_tests/basic_crate/target/fuzzcheck/x86_64-unknown-linux-gnu/release/deps/basic_crate-355b4a7b4d1de335+0x236668) (BuildId: faf06c4db8d903caa5edfc5b0ddaf8fc28b78ab2)
        #12 0x55c662e3e717  (~/dev/fuzzcheck/usage_tests/basic_crate/target/fuzzcheck/x86_64-unknown-linux-gnu/release/deps/basic_crate-355b4a7b4d1de335+0x22a717) (BuildId: faf06c4db8d903caa5edfc5b0ddaf8fc28b78ab2)
        #13 0x55c662e00498  (~/dev/fuzzcheck/usage_tests/basic_crate/target/fuzzcheck/x86_64-unknown-linux-gnu/release/deps/basic_crate-355b4a7b4d1de335+0x1ec498) (BuildId: faf06c4db8d903caa5edfc5b0ddaf8fc28b78ab2)
        #14 0x55c662e392ea  (~/dev/fuzzcheck/usage_tests/basic_crate/target/fuzzcheck/x86_64-unknown-linux-gnu/release/deps/basic_crate-355b4a7b4d1de335+0x2252ea) (BuildId: faf06c4db8d903caa5edfc5b0ddaf8fc28b78ab2)
        #15 0x55c662e8e0c2  (~/dev/fuzzcheck/usage_tests/basic_crate/target/fuzzcheck/x86_64-unknown-linux-gnu/release/deps/basic_crate-355b4a7b4d1de335+0x27a0c2) (BuildId: faf06c4db8d903caa5edfc5b0ddaf8fc28b78ab2)
        #16 0x55c662e8cdfb  (~/dev/fuzzcheck/usage_tests/basic_crate/target/fuzzcheck/x86_64-unknown-linux-gnu/release/deps/basic_crate-355b4a7b4d1de335+0x278dfb) (BuildId: faf06c4db8d903caa5edfc5b0ddaf8fc28b78ab2)
        #17 0x55c662e8bfbf  (~/dev/fuzzcheck/usage_tests/basic_crate/target/fuzzcheck/x86_64-unknown-linux-gnu/release/deps/basic_crate-355b4a7b4d1de335+0x277fbf) (BuildId: faf06c4db8d903caa5edfc5b0ddaf8fc28b78ab2)
        #18 0x55c662e8a735  (~/dev/fuzzcheck/usage_tests/basic_crate/target/fuzzcheck/x86_64-unknown-linux-gnu/release/deps/basic_crate-355b4a7b4d1de335+0x276735) (BuildId: faf06c4db8d903caa5edfc5b0ddaf8fc28b78ab2)
        #19 0x55c662e84fdb  (~/dev/fuzzcheck/usage_tests/basic_crate/target/fuzzcheck/x86_64-unknown-linux-gnu/release/deps/basic_crate-355b4a7b4d1de335+0x270fdb) (BuildId: faf06c4db8d903caa5edfc5b0ddaf8fc28b78ab2)
        #20 0x55c662e6da8f  (~/dev/fuzzcheck/usage_tests/basic_crate/target/fuzzcheck/x86_64-unknown-linux-gnu/release/deps/basic_crate-355b4a7b4d1de335+0x259a8f) (BuildId: faf06c4db8d903caa5edfc5b0ddaf8fc28b78ab2)
        #21 0x55c662e82ede  (~/dev/fuzzcheck/usage_tests/basic_crate/target/fuzzcheck/x86_64-unknown-linux-gnu/release/deps/basic_crate-355b4a7b4d1de335+0x26eede) (BuildId: faf06c4db8d903caa5edfc5b0ddaf8fc28b78ab2)
        #22 0x55c662e83dc3  (~/dev/fuzzcheck/usage_tests/basic_crate/target/fuzzcheck/x86_64-unknown-linux-gnu/release/deps/basic_crate-355b4a7b4d1de335+0x26fdc3) (BuildId: faf06c4db8d903caa5edfc5b0ddaf8fc28b78ab2)
        #23 0x55c662dd9a72  (~/dev/fuzzcheck/usage_tests/basic_crate/target/fuzzcheck/x86_64-unknown-linux-gnu/release/deps/basic_crate-355b4a7b4d1de335+0x1c5a72) (BuildId: faf06c4db8d903caa5edfc5b0ddaf8fc28b78ab2)
        #24 0x55c662dfd118  (~/dev/fuzzcheck/usage_tests/basic_crate/target/fuzzcheck/x86_64-unknown-linux-gnu/release/deps/basic_crate-355b4a7b4d1de335+0x1e9118) (BuildId: faf06c4db8d903caa5edfc5b0ddaf8fc28b78ab2)
        #25 0x55c662fee0b9  (~/dev/fuzzcheck/usage_tests/basic_crate/target/fuzzcheck/x86_64-unknown-linux-gnu/release/deps/basic_crate-355b4a7b4d1de335+0x3da0b9) (BuildId: faf06c4db8d903caa5edfc5b0ddaf8fc28b78ab2)
        #26 0x55c662df8e91  (~/dev/fuzzcheck/usage_tests/basic_crate/target/fuzzcheck/x86_64-unknown-linux-gnu/release/deps/basic_crate-355b4a7b4d1de335+0x1e4e91) (BuildId: faf06c4db8d903caa5edfc5b0ddaf8fc28b78ab2)
        #27 0x7f4d5eecdd8f  (/lib/x86_64-linux-gnu/libc.so.6+0x29d8f) (BuildId: 89c3cb85f9e55046776471fed05ec441581d1969)
        #28 0x7f4d5eecde3f  (/lib/x86_64-linux-gnu/libc.so.6+0x29e3f) (BuildId: 89c3cb85f9e55046776471fed05ec441581d1969)
        #29 0x55c662d1b144  (~/dev/fuzzcheck/usage_tests/basic_crate/target/fuzzcheck/x86_64-unknown-linux-gnu/release/deps/basic_crate-355b4a7b4d1de335+0x107144) (BuildId: faf06c4db8d903caa5edfc5b0ddaf8fc28b78ab2)
    
    Address 0x625000013fa0 is a wild pointer inside of access range of size 0x000000000010.
    SUMMARY: AddressSanitizer: heap-buffer-overflow (~/dev/fuzzcheck/usage_tests/basic_crate/target/fuzzcheck/x86_64-unknown-linux-gnu/release/deps/basic_crate-355b4a7b4d1de335+0x1290c1) (BuildId: faf06c4db8d903caa5edfc5b0ddaf8fc28b78ab2)
    Shadow bytes around the buggy address:
      0x0c4a7fffa7a0: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
      0x0c4a7fffa7b0: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
      0x0c4a7fffa7c0: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
      0x0c4a7fffa7d0: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
      0x0c4a7fffa7e0: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
    =>0x0c4a7fffa7f0: fa fa fa fa[fa]fa fa fa fa fa fa fa f1 f1 f1 f1
      0x0c4a7fffa800: f8 f2 f2 f2 f8 f8 f8 f2 f2 f2 f2 f2 f8 f8 f8 f2
      0x0c4a7fffa810: f2 f2 f2 f2 f8 f8 f2 f2 f8 f8 f8 f2 f2 f2 f2 f2
      0x0c4a7fffa820: f8 f8 f8 f8 f2 f2 f2 f2 f8 f8 f8 f8 f8 f8 f2 f2
      0x0c4a7fffa830: f2 f2 f8 f8 f2 f2 f8 f8 f8 f2 f2 f2 f2 f2 f8 f8
      0x0c4a7fffa840: f8 f8 f2 f2 f2 f2 f8 f8 f8 f8 f8 f8 f2 f2 f2 f2
    Shadow byte legend (one shadow byte represents 8 application bytes):
      Addressable:           00
      Partially addressable: 01 02 03 04 05 06 07
      Heap left redzone:       fa
      Freed heap region:       fd
      Stack left redzone:      f1
      Stack mid redzone:       f2
      Stack right redzone:     f3
      Stack after return:      f5
      Stack use after scope:   f8
      Global redzone:          f9
      Global init order:       f6
      Poisoned by user:        f7
      Container overflow:      fc
      Array cookie:            ac
      Intra object redzone:    bb
      ASan internal:           fe
      Left alloca redzone:     ca
      Right alloca redzone:    cb
    ==428240==ABORTING
    

    possibly relevant platform details:

    $ uname -a
    Linux XXX 5.17.15-76051715-generic #202206141358~1655919116~22.04~1db9e34 SMP PREEMPT Wed Jun 22 19 x86_64 x86_64 x86_64 GNU/Linux
    
    opened by phlip9 4
  • Linking issue with example fuzzer code

    Linking issue with example fuzzer code

    error: linking with `cc` failed: exit code: 1
      |
      = note: "cc" "-Wl,--as-needed" "-Wl,-z,noexecstack" "-m64" "-Wl,--eh-frame-hdr" "-Wl,-plugin=1" "-Wl,-plugin-opt=O3" "-Wl,-plugin-opt=mcpu=skylake" "-L" "/home/christophe/.rustup/toolchains/nightly-2021-02-20-x86_64-unknown-linux-gnu/lib/rustlib/x86_64-unknown-linux-gnu/lib" "/home/christophe/Code/encircle/query-optimization/fuzz/instrumented/target/x86_64-unknown-linux-gnu/release/deps/query_optimization.query_optimization.8ylrw7si-cgu.0.rcgu.o" "-o" "/home/christophe/Code/encircle/query-optimization/fuzz/instrumented/target/x86_64-unknown-linux-gnu/release/deps/libquery_optimization.so" "-Wl,--version-script=/tmp/rustctTGZXv/list" "/home/christophe/Code/encircle/query-optimization/fuzz/instrumented/target/x86_64-unknown-linux-gnu/release/deps/query_optimization.4vv4bvlcpeqs8lta.rcgu.o" "-shared" "-Wl,-zrelro" "-Wl,-znow" "-Wl,-O1" "-nodefaultlibs" "-L" "/home/christophe/Code/encircle/query-optimization/fuzz/instrumented/target/x86_64-unknown-linux-gnu/release/deps" "-L" "/home/christophe/Code/encircle/query-optimization/fuzz/instrumented/target/release/deps" "-L" "/home/christophe/.rustup/toolchains/nightly-2021-02-20-x86_64-unknown-linux-gnu/lib/rustlib/x86_64-unknown-linux-gnu/lib" "-Wl,-Bstatic" "-Wl,--whole-archive" "/tmp/rustctTGZXv/libitertools-11c0588956c1a9e9.rlib" "-Wl,--no-whole-archive" "-Wl,--whole-archive" "/tmp/rustctTGZXv/libeither-9c441606e1522bc4.rlib" "-Wl,--no-whole-archive" "-Wl,--whole-archive" "/tmp/rustctTGZXv/libmemory_usage-a9daf975c5269191.rlib" "-Wl,--no-whole-archive" "-Wl,--whole-archive" "/tmp/rustctTGZXv/libpetgraph-d4a1ca2a4584a6ac.rlib" "-Wl,--no-whole-archive" "-Wl,--whole-archive" "/tmp/rustctTGZXv/libordermap-9ae9dcc2fa2a157d.rlib" "-Wl,--no-whole-archive" "-Wl,--whole-archive" "/tmp/rustctTGZXv/libfixedbitset-d5c84f681dbdfbe2.rlib" "-Wl,--no-whole-archive" "-Wl,--start-group" "-L" "/home/christophe/.rustup/toolchains/nightly-2021-02-20-x86_64-unknown-linux-gnu/lib/rustlib/x86_64-unknown-linux-gnu/lib" "-Wl,-Bdynamic" "-lstd-6f5658153d127ddd" "-Wl,--end-group" "-Wl,-Bstatic" "/tmp/rustctTGZXv/libcompiler_builtins-ea377e9224b11a8a.rlib" "-Wl,-Bdynamic" "-lgcc_s" "-lutil" "-lrt" "-lpthread" "-lm" "-ldl" "-lc" "-fuse-ld=gold"
      = note: /usr/bin/ld.gold: error: 1: could not load plugin library: 1: cannot open shared object file: No such file or directory
              /usr/bin/ld.gold: error: /home/christophe/Code/encircle/query-optimization/fuzz/instrumented/target/x86_64-unknown-linux-gnu/release/deps/query_optimization.query_optimization.8ylrw7si-cgu.0.rcgu.o:1:3: invalid character
              /usr/bin/ld.gold: error: /home/christophe/Code/encircle/query-optimization/fuzz/instrumented/target/x86_64-unknown-linux-gnu/release/deps/query_optimization.query_optimization.8ylrw7si-cgu.0.rcgu.o:1:3: syntax error, unexpected $end
              /usr/bin/ld.gold: error: /home/christophe/Code/encircle/query-optimization/fuzz/instrumented/target/x86_64-unknown-linux-gnu/release/deps/query_optimization.query_optimization.8ylrw7si-cgu.0.rcgu.o: not an object or archive
              /usr/bin/ld.gold: error: /home/christophe/Code/encircle/query-optimization/fuzz/instrumented/target/x86_64-unknown-linux-gnu/release/deps/query_optimization.4vv4bvlcpeqs8lta.rcgu.o:1:3: invalid character
              /usr/bin/ld.gold: error: /home/christophe/Code/encircle/query-optimization/fuzz/instrumented/target/x86_64-unknown-linux-gnu/release/deps/query_optimization.4vv4bvlcpeqs8lta.rcgu.o:1:3: syntax error, unexpected $end
              /usr/bin/ld.gold: error: /home/christophe/Code/encircle/query-optimization/fuzz/instrumented/target/x86_64-unknown-linux-gnu/release/deps/query_optimization.4vv4bvlcpeqs8lta.rcgu.o: not an object or archive
              /usr/bin/ld.gold: error: /tmp/rustctTGZXv/libitertools-11c0588956c1a9e9.rlib: plugin failed to claim member itertools-11c0588956c1a9e9.itertools.6c2ysjm2-cgu.0.rcgu.o at 956
              /usr/bin/ld.gold: error: /tmp/rustctTGZXv/libeither-9c441606e1522bc4.rlib: plugin failed to claim member either-9c441606e1522bc4.either.e7ks6amo-cgu.0.rcgu.o at 190
              /usr/bin/ld.gold: error: /tmp/rustctTGZXv/libmemory_usage-a9daf975c5269191.rlib: plugin failed to claim member memory_usage-a9daf975c5269191.memory_usage.6iqros1j-cgu.0.rcgu.o at 506
              /usr/bin/ld.gold: error: /tmp/rustctTGZXv/libpetgraph-d4a1ca2a4584a6ac.rlib: plugin failed to claim member petgraph-d4a1ca2a4584a6ac.petgraph.80g7g297-cgu.0.rcgu.o at 2304
              /usr/bin/ld.gold: error: /tmp/rustctTGZXv/libordermap-9ae9dcc2fa2a157d.rlib: plugin failed to claim member ordermap-9ae9dcc2fa2a157d.ordermap.ctam39c9-cgu.0.rcgu.o at 364
              /usr/bin/ld.gold: error: /tmp/rustctTGZXv/libfixedbitset-d5c84f681dbdfbe2.rlib: plugin failed to claim member fixedbitset-d5c84f681dbdfbe2.fixedbitset.8vnrbsqo-cgu.0.rcgu.o at 920
              collect2: error: ld returned 1 exit status
    

    The part -Wl,-plugin=1 seems to be the cause, but I can't find whether it is the expected name for an actual linker plugin, or is the root cause of the bug. I've tried a few versions of nightly in case the issue was due to breakage with newer versions, but 2021-02-20 (used here) is basically from when the last release went out.

    opened by christophebiocca 4
Owner
Loïc Lecrenier
Loïc Lecrenier
Advanced Fuzzing Library - Slot your Fuzzer together in Rust! Scales across cores and machines. For Windows, Android, MacOS, Linux, no_std, ...

LibAFL, the fuzzer library. Advanced Fuzzing Library - Slot your own fuzzers together and extend their features using Rust. LibAFL is written and main

Advanced Fuzzing League ++ 1.2k Jan 6, 2023
A self-hosted Fuzzing-As-A-Service platform

OneFuzz A self-hosted Fuzzing-As-A-Service platform Project OneFuzz enables continuous developer-driven fuzzing to proactively harden software prior t

Microsoft 2.6k Jan 8, 2023
Brave's Rust-based adblock engine

Ad Block engine in Rust Native Rust module for Adblock Plus syntax (e.g. EasyList, EasyPrivacy) filter parsing and matching. It uses a tokenisation ap

Brave Software 961 Jan 5, 2023
symbolic execution engine for Rust

Seer: Symbolic Execution Engine for Rust Seer is a fork of miri that adds support for symbolic execution, using z3 as a solver backend. Given a progra

David Renshaw 313 Dec 26, 2022
Symbolic execution of LLVM IR with an engine written in Rust

haybale: Symbolic execution of LLVM IR, written in Rust haybale is a general-purpose symbolic execution engine written in Rust. It operates on LLVM IR

UCSD PLSysSec 404 Jan 1, 2023
Kepler is a vulnerability database and lookup store and API currently utilising National Vulnerability Database and NPM Advisories as data sources

Kepler — Kepler is a vulnerability database and lookup store and API currently utilising National Vulnerability Database and NPM Advisories as data so

Exein.io 101 Nov 12, 2022
Steals browser passwords and cookies and sends to webhook.

Browser-Stealer Steals browser passwords and cookies and sends to webhook. Donating Educational Purposes Only This code is made so you can learn from

RadonCoding 3 Sep 27, 2021
Xori is an automation-ready disassembly and static analysis library for PE32, 32+ and shellcode

Xori - Custom disassembly framework Xori is an automation-ready disassembly and static analysis library that consumes shellcode or PE binaries and pro

ENDGAME 712 Nov 28, 2022
🕵️‍♀️ Find, locate, and query files for ops and security experts ⚡️⚡️⚡️

Recon Find, locate, and query files for ops and security experts Key Features • How To Use • Download • Contributing • License Key Features Query with

Rusty Ferris Club 11 Dec 16, 2022
Detects usage of unsafe Rust in a Rust crate and its dependencies.

cargo-geiger ☢️ Looking for maintainer: https://github.com/rust-secure-code/cargo-geiger/issues/210 A program that lists statistics related to the usa

Rust Secure Code Working Group 1.1k Jan 4, 2023
An esoteric language/compiler written with Rust and Rust LLVM bindings

MeidoLang (メイドラング) A not so useful and esoteric language. The goal of this project was to contain some quirky or novel syntax in a stack-style program

null 0 Dec 24, 2021
Rust-verification-tools - RVT is a collection of tools/libraries to support both static and dynamic verification of Rust programs.

Rust verification tools This is a collection of tools/libraries to support both static and dynamic verification of Rust programs. We see static verifi

null 253 Dec 31, 2022
link is a command and control framework written in rust

link link is a command and control framework written in rust. Currently in alpha. Table of Contents Introduction Features Feedback Build Process Ackno

null 427 Dec 24, 2022
Rust library for building and running BPF/eBPF modules

RedBPF A Rust eBPF toolchain. Overview The redbpf project is a collection of tools and libraries to build eBPF programs using Rust. It includes: redbp

foniod 1.5k Jan 1, 2023
A rust program to bruteforce ZIP, PDF and some popular hashes.

Veldora A program to bruteforce zips, pdfs and some popular hashes. This is basically a rust version of bruttle, but a lot faster. Installation: git c

Aquib 30 Dec 28, 2022
OpenSK is an open-source implementation for security keys written in Rust that supports both FIDO U2F and FIDO2 standards.

OpenSK This repository contains a Rust implementation of a FIDO2 authenticator. We developed OpenSK as a Tock OS application. We intend to bring a ful

Google 2.4k Jan 7, 2023
A fast Rust-based safe and thead-friendly grammar-based fuzz generator

Intro fzero is a grammar-based fuzzer that generates a Rust application inspired by the paper "Building Fast Fuzzers" by Rahul Gopinath and Andreas Ze

null 203 Nov 9, 2022
☢ Guerrilla (or Monkey) Patching in Rust for (unsafe) fun and profit.

Guerrilla Guerrilla (or Monkey) Patching in Rust for (unsafe) fun and profit. Provides aribtrary monkey patching in Rust. Please do not use this crate

Ryan Leckey 97 Dec 16, 2022
Breaking your Rust code for fun and profit

Breaking your Rust code for fun & profit this is an architecture-preview, not all components are there This is a mutation testing framework for Rust c

null 542 Jan 4, 2023