Fuzzing: upgrade to latest deps and fix build.

Fixes #7.
This commit is contained in:
Chris Fallin 2024-03-29 16:38:07 -07:00
parent b2967e0b84
commit 213edc11e7
4 changed files with 196 additions and 228 deletions

View file

@ -11,11 +11,11 @@ cargo-fuzz = true
[dependencies] [dependencies]
libfuzzer-sys = "0.4" libfuzzer-sys = "0.4"
wasm-smith = "0.8" wasm-smith = "0.202.0"
env_logger = "0.9" env_logger = "0.9"
log = "0.4" log = "0.4"
wasmparser = "0.95" wasmparser = "0.202.0"
wasmtime = "7.0" wasmtime = "19.0"
[dependencies.waffle] [dependencies.waffle]
path = ".." path = ".."

View file

@ -4,12 +4,12 @@ use std::sync::atomic::{AtomicU64, Ordering};
use waffle::{FrontendOptions, Module}; use waffle::{FrontendOptions, Module};
fuzz_target!( fuzz_target!(|module: waffle::fuzzing::ArbitraryModule| {
|module: wasm_smith::ConfiguredModule<waffle::fuzzing::Config>| { let module = module.0;
let _ = env_logger::try_init(); let _ = env_logger::try_init();
log::debug!("original module: {:?}", module.module); log::debug!("original module: {:?}", module);
let orig_bytes = module.module.to_bytes(); let orig_bytes = module.to_bytes();
if waffle::fuzzing::reject(&orig_bytes[..]) { if waffle::fuzzing::reject(&orig_bytes[..]) {
log::debug!("Discarding fuzz run. Body:\n{:?}", module); log::debug!("Discarding fuzz run. Body:\n{:?}", module);
@ -24,8 +24,7 @@ fuzz_target!(
let orig_module = let orig_module =
wasmtime::Module::new(&engine, &orig_bytes[..]).expect("failed to parse original wasm"); wasmtime::Module::new(&engine, &orig_bytes[..]).expect("failed to parse original wasm");
let mut orig_store = wasmtime::Store::new(&engine, ()); let mut orig_store = wasmtime::Store::new(&engine, ());
orig_store.out_of_fuel_trap(); orig_store.set_fuel(10000).unwrap();
orig_store.add_fuel(10000).unwrap();
let orig_instance = wasmtime::Instance::new(&mut orig_store, &orig_module, &[]); let orig_instance = wasmtime::Instance::new(&mut orig_store, &orig_module, &[]);
let orig_instance = match orig_instance { let orig_instance = match orig_instance {
Ok(orig_instance) => orig_instance, Ok(orig_instance) => orig_instance,
@ -51,13 +50,11 @@ fuzz_target!(
let roundtrip_module = wasmtime::Module::new(&engine, &roundtrip_bytes[..]) let roundtrip_module = wasmtime::Module::new(&engine, &roundtrip_bytes[..])
.expect("failed to parse roundtripped wasm"); .expect("failed to parse roundtripped wasm");
let mut roundtrip_store = wasmtime::Store::new(&engine, ()); let mut roundtrip_store = wasmtime::Store::new(&engine, ());
roundtrip_store.out_of_fuel_trap();
// After roundtrip, fuel consumption rate may differ. That's fine; // After roundtrip, fuel consumption rate may differ. That's fine;
// what matters is that it terminated above without a trap (hence // what matters is that it terminated above without a trap (hence
// halts in a reasonable time). // halts in a reasonable time).
roundtrip_store.add_fuel(u64::MAX).unwrap(); roundtrip_store.set_fuel(u64::MAX).unwrap();
let roundtrip_instance = let roundtrip_instance = wasmtime::Instance::new(&mut roundtrip_store, &roundtrip_module, &[])
wasmtime::Instance::new(&mut roundtrip_store, &roundtrip_module, &[])
.expect("cannot instantiate roundtripped wasm"); .expect("cannot instantiate roundtripped wasm");
// Ensure exports are equal. // Ensure exports are equal.
@ -110,8 +107,7 @@ fuzz_target!(
} }
success(total); success(total);
} });
);
static TOTAL: AtomicU64 = AtomicU64::new(0); static TOTAL: AtomicU64 = AtomicU64::new(0);
static SUCCESS: AtomicU64 = AtomicU64::new(0); static SUCCESS: AtomicU64 = AtomicU64::new(0);

View file

@ -3,12 +3,12 @@ use libfuzzer_sys::fuzz_target;
use waffle::{FrontendOptions, InterpContext, InterpResult, Module}; use waffle::{FrontendOptions, InterpContext, InterpResult, Module};
fuzz_target!( fuzz_target!(|module: waffle::fuzzing::ArbitraryModule| {
|module: wasm_smith::ConfiguredModule<waffle::fuzzing::Config>| { let module = module.0;
let _ = env_logger::try_init(); let _ = env_logger::try_init();
log::debug!("original module: {:?}", module.module); log::debug!("original module: {:?}", module);
let orig_bytes = module.module.to_bytes(); let orig_bytes = module.to_bytes();
if waffle::fuzzing::reject(&orig_bytes[..]) { if waffle::fuzzing::reject(&orig_bytes[..]) {
log::debug!("Discarding fuzz run. Body:\n{:?}", module); log::debug!("Discarding fuzz run. Body:\n{:?}", module);
@ -64,5 +64,4 @@ fuzz_target!(
assert_eq!(orig_ctx.memories, opt_ctx.memories); assert_eq!(orig_ctx.memories, opt_ctx.memories);
assert_eq!(orig_ctx.globals, opt_ctx.globals); assert_eq!(orig_ctx.globals, opt_ctx.globals);
} });
);

View file

@ -23,10 +23,10 @@ pub fn reject(bytes: &[u8]) -> bool {
wasmparser::Payload::StartSection { .. } => { wasmparser::Payload::StartSection { .. } => {
has_start = true; has_start = true;
} }
wasmparser::Payload::ExportSection(mut reader) => { wasmparser::Payload::ExportSection(reader) => {
for _ in 0..reader.get_count() { for export in reader {
let e = reader.read().unwrap(); let export = export.unwrap();
match &e.kind { match &export.kind {
&wasmparser::ExternalKind::Global => { &wasmparser::ExternalKind::Global => {
num_globals += 1; num_globals += 1;
} }
@ -34,10 +34,10 @@ pub fn reject(bytes: &[u8]) -> bool {
} }
} }
} }
wasmparser::Payload::MemorySection(mut reader) => { wasmparser::Payload::MemorySection(reader) => {
for _ in 0..reader.get_count() { for mem in reader {
let m = reader.read().unwrap(); let mem = mem.unwrap();
if m.maximum.is_none() || m.maximum.unwrap() > 100 { if mem.maximum.is_none() || mem.maximum.unwrap() > 100 {
return true; return true;
} }
} }
@ -53,59 +53,32 @@ pub fn reject(bytes: &[u8]) -> bool {
false false
} }
pub fn fuzzing_config() -> wasm_smith::Config {
wasm_smith::Config {
min_funcs: 1,
max_funcs: 1,
min_memories: 1,
max_memories: 1,
min_globals: 10,
max_globals: 10,
min_tables: 0,
max_tables: 0,
min_imports: 0,
max_imports: 0,
min_exports: 12,
max_exports: 12,
allow_start_export: true,
canonicalize_nans: true,
max_memory32_pages: 1,
..Default::default()
}
}
#[derive(Debug)] #[derive(Debug)]
pub struct Config; pub struct ArbitraryModule(pub wasm_smith::Module);
impl<'a> arbitrary::Arbitrary<'a> for Config { impl<'a> arbitrary::Arbitrary<'a> for ArbitraryModule {
fn arbitrary(_u: &mut arbitrary::Unstructured<'a>) -> arbitrary::Result<Self> { fn arbitrary(u: &mut arbitrary::Unstructured<'_>) -> arbitrary::Result<Self> {
Ok(Config) Ok(Self(wasm_smith::Module::new(fuzzing_config(), u)?))
}
}
impl wasm_smith::Config for Config {
fn min_funcs(&self) -> usize {
1
}
fn max_funcs(&self) -> usize {
1
}
fn min_memories(&self) -> u32 {
1
}
fn max_memories(&self) -> usize {
1
}
fn min_globals(&self) -> usize {
10
}
fn max_globals(&self) -> usize {
10
}
fn min_tables(&self) -> u32 {
0
}
fn max_tables(&self) -> usize {
0
}
fn min_imports(&self) -> usize {
0
}
fn max_imports(&self) -> usize {
0
}
fn min_exports(&self) -> usize {
12
}
fn max_exports(&self) -> usize {
12
}
fn allow_start_export(&self) -> bool {
true
}
fn canonicalize_nans(&self) -> bool {
true
}
fn max_memory_pages(&self, _is_64: bool) -> u64 {
1
} }
} }