diff --git a/cranelift/FUZZING.md b/cranelift/FUZZING.md new file mode 100644 index 0000000000..a542e139d6 --- /dev/null +++ b/cranelift/FUZZING.md @@ -0,0 +1,9 @@ +# Fuzzing + +This document describes how to fuzz cretonne with [`cargo-fuzz`](https://github.com/rust-fuzz/cargo-fuzz). The fuzz targets use `wasm-opt` from [`binaryen-rs`](https://github.com/pepyakin/binaryen-rs) to generate valid WebAssembly modules from the fuzzed input supplied by `cargo-fuzz` (via [libfuzzer](http://llvm.org/docs/LibFuzzer.html)). In this scheme coverage feedback from both cretonne and the `wasm-opt` input generation code is used to inform the fuzzer. + +# Usage + +1. Install all dependencies required to build `binaryen-rs` and `cargo-fuzz` (including `cmake`) +2. Use the rust nightly toolchain (required by `cargo-fuzz`): `rustup override set nightly` +3. Execute the fuzz target: `cargo fuzz run fuzz_translate_module` diff --git a/cranelift/fuzz/Cargo.toml b/cranelift/fuzz/Cargo.toml new file mode 100644 index 0000000000..d48922c1f4 --- /dev/null +++ b/cranelift/fuzz/Cargo.toml @@ -0,0 +1,29 @@ +[package] +name = "cton-wasm-fuzz" +version = "0.0.1" +authors = ["foote@fastly.com"] +publish = false + +[package.metadata] +cargo-fuzz = true + +[dependencies.cargo-fuzz] +version = "*" + +[dependencies.binaryen] +git = "https://github.com/pepyakin/binaryen-rs.git" +version = "*" + +[dependencies.libfuzzer-sys] +git = "https://github.com/rust-fuzz/libfuzzer-sys.git" + +[dependencies.cretonne-wasm] +path = "../lib/wasm" + +# Prevent this from interfering with workspaces +[workspace] +members = ["."] + +[[bin]] +name = "fuzz_translate_module" +path = "fuzz_translate_module.rs" diff --git a/cranelift/fuzz/corpus/fuzz_translate_module/ffaefab69523eb11935a9b420d58826c8ea65c4c b/cranelift/fuzz/corpus/fuzz_translate_module/ffaefab69523eb11935a9b420d58826c8ea65c4c new file mode 100644 index 0000000000..1fa4159954 Binary files /dev/null and b/cranelift/fuzz/corpus/fuzz_translate_module/ffaefab69523eb11935a9b420d58826c8ea65c4c differ diff --git a/cranelift/fuzz/fuzz_translate_module.rs b/cranelift/fuzz/fuzz_translate_module.rs new file mode 100644 index 0000000000..45180c14af --- /dev/null +++ b/cranelift/fuzz/fuzz_translate_module.rs @@ -0,0 +1,15 @@ +#![no_main] +#[macro_use] +extern crate libfuzzer_sys; +extern crate binaryen; +extern crate cretonne_wasm; +use cretonne_wasm::{translate_module, DummyEnvironment}; + +fuzz_target!(|data: &[u8]| { + let binaryen_module = binaryen::tools::translate_to_fuzz_mvp(data); + + let wasm = binaryen_module.write(); + + let mut dummy_environ = DummyEnvironment::default(); + translate_module(&wasm, &mut dummy_environ).unwrap(); +}); diff --git a/cranelift/test-all.sh b/cranelift/test-all.sh index 82ec347dac..96e81f1864 100755 --- a/cranelift/test-all.sh +++ b/cranelift/test-all.sh @@ -65,4 +65,19 @@ else echo "\`cargo +nightly install clippy\` for optional rust linting" fi +# Ensure fuzzer works by running it with a single input +# Note LSAN is disabled due to https://github.com/google/sanitizers/issues/764 +banner "cargo fuzz check" +if rustup toolchain list | grep -q nightly; then + if cargo install --list | grep -q cargo-fuzz; then + echo "cargo-fuzz found" + else + echo "installing cargo-fuzz" + cargo +nightly install cargo-fuzz + fi + ASAN_OPTIONS=detect_leaks=0 cargo +nightly fuzz run fuzz_translate_module $topdir/fuzz/corpus/fuzz_translate_module/ffaefab69523eb11935a9b420d58826c8ea65c4c +else + echo "nightly toolchain not found, skipping fuzz target integration test" +fi + banner "OK"