Merge pull request #3157 from alexcrichton/centralize-error-handling

fuzz: Centralize handling instantiation errors
This commit is contained in:
Nick Fitzgerald
2021-08-06 10:38:48 -07:00
committed by GitHub

View File

@@ -13,7 +13,6 @@
pub mod dummy; pub mod dummy;
use arbitrary::Arbitrary; use arbitrary::Arbitrary;
use dummy::dummy_linker;
use log::debug; use log::debug;
use std::sync::atomic::{AtomicUsize, Ordering::SeqCst}; use std::sync::atomic::{AtomicUsize, Ordering::SeqCst};
use std::sync::{Arc, Condvar, Mutex}; use std::sync::{Arc, Condvar, Mutex};
@@ -172,39 +171,33 @@ pub fn instantiate_with_config(
Err(_) if !known_valid => return, Err(_) if !known_valid => return,
Err(e) => panic!("failed to compile module: {:?}", e), Err(e) => panic!("failed to compile module: {:?}", e),
}; };
let linker = match dummy_linker(&mut store, &module) {
Ok(linker) => linker,
Err(e) => {
eprintln!("Warning: failed to create host imports: {:?}", e);
// Currently the only error we want to allow here is ones where we instantiate_with_dummy(&mut store, &module);
// ran out of resources creating imports. For example memory
// creation may not succeed if the host is running low on resources.
//
// Other errors, however, are bugs in creation of the host resource.
let string = e.to_string();
assert!(
string.contains("Insufficient resources")
&& string.contains("exceeds memory limits")
);
return;
} }
fn instantiate_with_dummy(store: &mut Store<StoreLimits>, module: &Module) -> Option<Instance> {
// Creation of imports can fail due to resource limit constraints, and then
// instantiation can naturally fail for a number of reasons as well. Bundle
// the two steps together to match on the error below.
let instance =
dummy::dummy_linker(store, module).and_then(|l| l.instantiate(&mut *store, module));
let e = match instance {
Ok(i) => return Some(i),
Err(e) => e,
}; };
match linker.instantiate(&mut store, &module) {
Ok(_) => {}
Err(e) => {
// If the instantiation hit OOM for some reason then that's ok, it's // If the instantiation hit OOM for some reason then that's ok, it's
// expected that fuzz-generated programs try to allocate lots of // expected that fuzz-generated programs try to allocate lots of
// stuff. // stuff.
if store.data().oom { if store.data().oom {
return; return None;
} }
// Allow traps which can happen normally with `unreachable` or a // Allow traps which can happen normally with `unreachable` or a
// timeout or such // timeout or such
if e.downcast_ref::<Trap>().is_some() { if e.downcast_ref::<Trap>().is_some() {
return; return None;
} }
let string = e.to_string(); let string = e.to_string();
@@ -215,14 +208,12 @@ pub fn instantiate_with_config(
// rather than positional-based resolution // rather than positional-based resolution
|| string.contains("incompatible import type") || string.contains("incompatible import type")
{ {
return; return None;
} }
// Everything else should be a bug in the fuzzer // Everything else should be a bug in the fuzzer or a bug in wasmtime
panic!("failed to instantiate {:?}", e); panic!("failed to instantiate {:?}", e);
} }
}
}
/// Compile the Wasm buffer, and implicitly fail if we have an unexpected /// Compile the Wasm buffer, and implicitly fail if we have an unexpected
/// panic or segfault or anything else that can be detected "passively". /// panic or segfault or anything else that can be detected "passively".
@@ -286,27 +277,9 @@ pub fn differential_execution(
// in and with what values. Like the results of exported functions, // in and with what values. Like the results of exported functions,
// calls to imports should also yield the same values for each // calls to imports should also yield the same values for each
// configuration, and we should assert that. // configuration, and we should assert that.
let linker = match dummy_linker(&mut store, &module) { let instance = match instantiate_with_dummy(&mut store, &module) {
Ok(linker) => linker, Some(instance) => instance,
Err(e) => { None => continue,
eprintln!("Warning: failed to create host imports: {:?}", e);
continue;
}
};
// Don't unwrap this: there can be instantiation-/link-time errors that
// aren't caught during validation or compilation. For example, an imported
// table might not have room for an element segment that we want to
// initialize into it.
let instance = match linker.instantiate(&mut store, &module) {
Ok(instance) => instance,
Err(e) => {
eprintln!(
"Warning: failed to instantiate `wasm-opt -ttf` module: {}",
e
);
continue;
}
}; };
let exports = instance let exports = instance
@@ -462,16 +435,7 @@ pub fn make_api_calls(api: crate::generators::api::ApiCalls) {
}; };
let store = store.as_mut().unwrap(); let store = store.as_mut().unwrap();
let linker = match dummy_linker(store, module) { if let Some(instance) = instantiate_with_dummy(store, module) {
Ok(linker) => linker,
Err(_) => continue,
};
// Don't unwrap this: there can be instantiation-/link-time errors that
// aren't caught during validation or compilation. For example, an imported
// table might not have room for an element segment that we want to
// initialize into it.
if let Ok(instance) = linker.instantiate(store, &module) {
instances.insert(id, instance); instances.insert(id, instance);
} }
} }