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 |
This directory contains the necessary parts for building a library with FFI |
||||
access to the Wasm spec interpreter. Its major parts: |
access to the Wasm spec interpreter. Its major parts: |
||||
- `spec`: the Wasm spec code as a Git submodule (you may need to retrieve it: |
- `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 |
- `interpret.ml`: a shim layer for calling the Wasm spec code and exposing it |
||||
for FFI access |
for FFI access |
||||
- `Makefile`: the steps for gluing these pieces together into a static library |
- `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