Fix fuzzers requesting 4gb memories (#3029)
Wasmtime was updated to reject creation of memories exactly 4gb in size in #3013, but the fuzzers still had the assumption that any request to create a host object for a particular wasm type would succeed. Unfortunately now, though, a request to create a 4gb memory fails. This is an expected failure, though, so the fix here was to catch the error and allow it.
This commit is contained in:
@@ -137,7 +137,24 @@ 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 = dummy_linker(&mut store, &module);
|
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
|
||||||
|
// 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;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
match linker.instantiate(&mut store, &module) {
|
match linker.instantiate(&mut store, &module) {
|
||||||
Ok(_) => {}
|
Ok(_) => {}
|
||||||
@@ -227,7 +244,13 @@ 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 = dummy_linker(&mut store, &module);
|
let linker = match dummy_linker(&mut store, &module) {
|
||||||
|
Ok(linker) => linker,
|
||||||
|
Err(e) => {
|
||||||
|
eprintln!("Warning: failed to create host imports: {:?}", e);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
// Don't unwrap this: there can be instantiation-/link-time errors that
|
// Don't unwrap this: there can be instantiation-/link-time errors that
|
||||||
// aren't caught during validation or compilation. For example, an imported
|
// aren't caught during validation or compilation. For example, an imported
|
||||||
@@ -397,7 +420,10 @@ pub fn make_api_calls(api: crate::generators::api::ApiCalls) {
|
|||||||
};
|
};
|
||||||
|
|
||||||
let store = store.as_mut().unwrap();
|
let store = store.as_mut().unwrap();
|
||||||
let linker = dummy_linker(store, module);
|
let linker = match dummy_linker(store, module) {
|
||||||
|
Ok(linker) => linker,
|
||||||
|
Err(_) => continue,
|
||||||
|
};
|
||||||
|
|
||||||
// Don't unwrap this: there can be instantiation-/link-time errors that
|
// Don't unwrap this: there can be instantiation-/link-time errors that
|
||||||
// aren't caught during validation or compilation. For example, an imported
|
// aren't caught during validation or compilation. For example, an imported
|
||||||
|
|||||||
@@ -1,48 +1,49 @@
|
|||||||
//! Dummy implementations of things that a Wasm module can import.
|
//! Dummy implementations of things that a Wasm module can import.
|
||||||
|
|
||||||
|
use anyhow::Result;
|
||||||
use std::fmt::Write;
|
use std::fmt::Write;
|
||||||
use wasmtime::*;
|
use wasmtime::*;
|
||||||
|
|
||||||
/// Create a set of dummy functions/globals/etc for the given imports.
|
/// Create a set of dummy functions/globals/etc for the given imports.
|
||||||
pub fn dummy_linker<'module, T>(store: &mut Store<T>, module: &Module) -> Linker<T> {
|
pub fn dummy_linker<'module, T>(store: &mut Store<T>, module: &Module) -> Result<Linker<T>> {
|
||||||
let mut linker = Linker::new(store.engine());
|
let mut linker = Linker::new(store.engine());
|
||||||
linker.allow_shadowing(true);
|
linker.allow_shadowing(true);
|
||||||
for import in module.imports() {
|
for import in module.imports() {
|
||||||
match import.name() {
|
match import.name() {
|
||||||
Some(name) => {
|
Some(name) => {
|
||||||
linker
|
linker
|
||||||
.define(import.module(), name, dummy_extern(store, import.ty()))
|
.define(import.module(), name, dummy_extern(store, import.ty())?)
|
||||||
.unwrap();
|
.unwrap();
|
||||||
}
|
}
|
||||||
None => match import.ty() {
|
None => match import.ty() {
|
||||||
ExternType::Instance(ty) => {
|
ExternType::Instance(ty) => {
|
||||||
for ty in ty.exports() {
|
for ty in ty.exports() {
|
||||||
linker
|
linker
|
||||||
.define(import.module(), ty.name(), dummy_extern(store, ty.ty()))
|
.define(import.module(), ty.name(), dummy_extern(store, ty.ty())?)
|
||||||
.unwrap();
|
.unwrap();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
other => {
|
other => {
|
||||||
linker
|
linker
|
||||||
.define_name(import.module(), dummy_extern(store, other))
|
.define_name(import.module(), dummy_extern(store, other)?)
|
||||||
.unwrap();
|
.unwrap();
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
linker
|
Ok(linker)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Construct a dummy `Extern` from its type signature
|
/// Construct a dummy `Extern` from its type signature
|
||||||
pub fn dummy_extern<T>(store: &mut Store<T>, ty: ExternType) -> Extern {
|
pub fn dummy_extern<T>(store: &mut Store<T>, ty: ExternType) -> Result<Extern> {
|
||||||
match ty {
|
Ok(match ty {
|
||||||
ExternType::Func(func_ty) => Extern::Func(dummy_func(store, func_ty)),
|
ExternType::Func(func_ty) => Extern::Func(dummy_func(store, func_ty)),
|
||||||
ExternType::Global(global_ty) => Extern::Global(dummy_global(store, global_ty)),
|
ExternType::Global(global_ty) => Extern::Global(dummy_global(store, global_ty)),
|
||||||
ExternType::Table(table_ty) => Extern::Table(dummy_table(store, table_ty)),
|
ExternType::Table(table_ty) => Extern::Table(dummy_table(store, table_ty)),
|
||||||
ExternType::Memory(mem_ty) => Extern::Memory(dummy_memory(store, mem_ty)),
|
ExternType::Memory(mem_ty) => Extern::Memory(dummy_memory(store, mem_ty)?),
|
||||||
ExternType::Instance(instance_ty) => Extern::Instance(dummy_instance(store, instance_ty)),
|
ExternType::Instance(instance_ty) => Extern::Instance(dummy_instance(store, instance_ty)),
|
||||||
ExternType::Module(module_ty) => Extern::Module(dummy_module(store.engine(), module_ty)),
|
ExternType::Module(module_ty) => Extern::Module(dummy_module(store.engine(), module_ty)),
|
||||||
}
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Construct a dummy function for the given function type
|
/// Construct a dummy function for the given function type
|
||||||
@@ -86,8 +87,8 @@ pub fn dummy_table<T>(store: &mut Store<T>, ty: TableType) -> Table {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Construct a dummy memory for the given memory type.
|
/// Construct a dummy memory for the given memory type.
|
||||||
pub fn dummy_memory<T>(store: &mut Store<T>, ty: MemoryType) -> Memory {
|
pub fn dummy_memory<T>(store: &mut Store<T>, ty: MemoryType) -> Result<Memory> {
|
||||||
Memory::new(store, ty).unwrap()
|
Memory::new(store, ty)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Construct a dummy instance for the given instance type.
|
/// Construct a dummy instance for the given instance type.
|
||||||
@@ -414,7 +415,7 @@ mod tests {
|
|||||||
#[test]
|
#[test]
|
||||||
fn dummy_memory_import() {
|
fn dummy_memory_import() {
|
||||||
let mut store = store();
|
let mut store = store();
|
||||||
let memory = dummy_memory(&mut store, MemoryType::new(Limits::at_least(1)));
|
let memory = dummy_memory(&mut store, MemoryType::new(Limits::at_least(1))).unwrap();
|
||||||
assert_eq!(memory.size(&store), 1);
|
assert_eq!(memory.size(&store), 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user