Browse Source
* Revert "Remove spec interpreter fuzz target temporarily (#3399)"
This reverts commit 25d3fa4d7b
.
* add support for differential fuzzing against verified OCaml interpreter
* formatting
* comments
* fix missing dep case
* fix build error
* fix unit tests?
* restore previous differential_v8 max_table config
* attempt: add OCaml deps
* fix interpeter github repo
* fix spec repo url
* fix zarith package
* fix unit test
pull/3868/head
Conrad Watt
3 years ago
committed by
GitHub
15 changed files with 142 additions and 59 deletions
@ -1,7 +1,10 @@ |
|||
This directory contains the necessary parts for building a library with FFI |
|||
access to the Wasm spec interpreter. Its major parts: |
|||
- `spec`: the Wasm spec code as a Git submodule (you may need to retrieve it: |
|||
`git clone https://github.com/bytecodealliance/wasm-spec-mirror). |
|||
`git clone https://github.com/conrad-watt/spec/tree/wasmtime_fuzzing). |
|||
- `interpret.ml`: a shim layer for calling the Wasm spec code and exposing it |
|||
for FFI access |
|||
- `Makefile`: the steps for gluing these pieces together into a static library |
|||
|
|||
Note: the makefile must be configured with the path to libgmp. See LIBGMP_PATHS |
|||
in the makefile. |
|||
|
@ -0,0 +1,47 @@ |
|||
#![no_main] |
|||
|
|||
use libfuzzer_sys::arbitrary::{Result, Unstructured}; |
|||
use libfuzzer_sys::fuzz_target; |
|||
use std::sync::atomic::{AtomicUsize, Ordering::SeqCst}; |
|||
use wasmtime_fuzzing::{generators, oracles}; |
|||
|
|||
// Keep track of how many WebAssembly modules we actually executed (i.e. ran to
|
|||
// completion) versus how many were tried.
|
|||
static TRIED: AtomicUsize = AtomicUsize::new(0); |
|||
static EXECUTED: AtomicUsize = AtomicUsize::new(0); |
|||
|
|||
fuzz_target!(|data: &[u8]| { |
|||
// errors in `run` have to do with not enough input in `data`, which we
|
|||
// ignore here since it doesn't affect how we'd like to fuzz.
|
|||
drop(run(data)); |
|||
}); |
|||
|
|||
fn run(data: &[u8]) -> Result<()> { |
|||
let mut u = Unstructured::new(data); |
|||
let mut config: generators::Config = u.arbitrary()?; |
|||
config.set_differential_config(); |
|||
|
|||
// Enable features that the spec interpreter has implemented
|
|||
config.module_config.config.multi_value_enabled = false; |
|||
|
|||
// TODO: this is a best-effort attempt to avoid errors caused by the
|
|||
// generated module exporting no functions.
|
|||
config.module_config.config.min_exports = 5; |
|||
config.module_config.config.max_exports = 5; |
|||
|
|||
let module = config.generate(&mut u, Some(1000))?; |
|||
let tried = TRIED.fetch_add(1, SeqCst); |
|||
let executed = match oracles::differential_spec_execution(&module.to_bytes(), &config) { |
|||
Some(_) => EXECUTED.fetch_add(1, SeqCst), |
|||
None => EXECUTED.load(SeqCst), |
|||
}; |
|||
if tried > 0 && tried % 1000 == 0 { |
|||
println!( |
|||
"=== Execution rate ({} executed modules / {} tried modules): {}% ===", |
|||
executed, |
|||
tried, |
|||
executed as f64 / tried as f64 * 100f64 |
|||
) |
|||
} |
|||
Ok(()) |
|||
} |
Loading…
Reference in new issue