Fuzz using precompiled modules on CI (#3788)
In working on #3787 I see now that our coverage of loading precompiled files specifically is somewhat lacking, so this adds a config option to the fuzzers where, if enabled, will round-trip all compiled modules through the filesystem to test out the mmapped-file case.
This commit is contained in:
@@ -17,7 +17,7 @@ use arbitrary::{Arbitrary, Unstructured};
|
||||
use std::sync::Arc;
|
||||
use std::time::Duration;
|
||||
use wasm_smith::SwarmConfig;
|
||||
use wasmtime::{Engine, LinearMemory, MemoryCreator, MemoryType, Store};
|
||||
use wasmtime::{Engine, LinearMemory, MemoryCreator, MemoryType, Module, Store};
|
||||
|
||||
#[derive(Arbitrary, Clone, Debug, PartialEq, Eq, Hash)]
|
||||
enum OptLevel {
|
||||
@@ -62,6 +62,7 @@ pub struct WasmtimeConfig {
|
||||
memory_config: MemoryConfig,
|
||||
force_jump_veneers: bool,
|
||||
memfd: bool,
|
||||
use_precompiled_cwasm: bool,
|
||||
}
|
||||
|
||||
#[derive(Arbitrary, Clone, Debug, Eq, Hash, PartialEq)]
|
||||
@@ -170,6 +171,26 @@ impl Config {
|
||||
Ok(Timeout::Fuel(100_000))
|
||||
}
|
||||
}
|
||||
|
||||
/// Compiles the `wasm` within the `engine` provided.
|
||||
///
|
||||
/// This notably will use `Module::{serialize,deserialize_file}` to
|
||||
/// round-trip if configured in the fuzzer.
|
||||
pub fn compile(&self, engine: &Engine, wasm: &[u8]) -> Result<Module> {
|
||||
// Propagate this error in case the caller wants to handle
|
||||
// valid-vs-invalid wasm.
|
||||
let module = Module::new(engine, wasm)?;
|
||||
if !self.wasmtime.use_precompiled_cwasm {
|
||||
return Ok(module);
|
||||
}
|
||||
|
||||
// Don't propagate these errors to prevent them from accidentally being
|
||||
// interpreted as invalid wasm, these should never fail on a
|
||||
// well-behaved host system.
|
||||
let file = tempfile::NamedTempFile::new().unwrap();
|
||||
std::fs::write(file.path(), module.serialize().unwrap()).unwrap();
|
||||
unsafe { Ok(Module::deserialize_file(engine, file.path()).unwrap()) }
|
||||
}
|
||||
}
|
||||
|
||||
struct UnalignedMemoryCreator;
|
||||
|
||||
@@ -143,7 +143,7 @@ pub fn instantiate(wasm: &[u8], known_valid: bool, config: &generators::Config,
|
||||
}
|
||||
|
||||
log_wasm(wasm);
|
||||
let module = match Module::new(store.engine(), wasm) {
|
||||
let module = match config.compile(store.engine(), wasm) {
|
||||
Ok(module) => module,
|
||||
Err(_) if !known_valid => return,
|
||||
Err(e) => panic!("failed to compile module: {:?}", e),
|
||||
@@ -222,7 +222,7 @@ pub fn differential_execution(
|
||||
log::debug!("fuzz config: {:?}", fuzz_config);
|
||||
|
||||
let mut store = fuzz_config.to_store();
|
||||
let module = Module::new(store.engine(), &wasm).unwrap();
|
||||
let module = fuzz_config.compile(store.engine(), &wasm).unwrap();
|
||||
|
||||
// TODO: we should implement tracing versions of these dummy imports
|
||||
// that record a trace of the order that imported functions were called
|
||||
@@ -432,7 +432,7 @@ pub fn table_ops(mut fuzz_config: generators::Config, ops: generators::table_ops
|
||||
|
||||
let wasm = ops.to_wasm_binary();
|
||||
log_wasm(&wasm);
|
||||
let module = match Module::new(store.engine(), &wasm) {
|
||||
let module = match fuzz_config.compile(store.engine(), &wasm) {
|
||||
Ok(m) => m,
|
||||
Err(_) => return,
|
||||
};
|
||||
@@ -736,7 +736,9 @@ fn differential_store(
|
||||
fuzz_config: &generators::Config,
|
||||
) -> (Module, Store<StoreLimits>) {
|
||||
let store = fuzz_config.to_store();
|
||||
let module = Module::new(store.engine(), &wasm).expect("Wasmtime can compile module");
|
||||
let module = fuzz_config
|
||||
.compile(store.engine(), wasm)
|
||||
.expect("Wasmtime can compile module");
|
||||
(module, store)
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user