Path: blob/main/fuzz/fuzz_targets/instantiate.rs
1691 views
#![no_main]12use libfuzzer_sys::arbitrary::{Arbitrary, Result, Unstructured};3use wasmtime_fuzzing::generators::Config;4use wasmtime_fuzzing::oracles::{Timeout, instantiate};5use wasmtime_fuzzing::single_module_fuzzer::KnownValid;67wasmtime_fuzzing::single_module_fuzzer!(execute gen_module);89#[derive(Debug)]10struct InstantiateInput {11config: Config,12timeout: Timeout,13}1415impl<'a> Arbitrary<'a> for InstantiateInput {16fn arbitrary(u: &mut Unstructured<'a>) -> Result<Self> {17let mut config: Config = u.arbitrary()?;1819// Pick either fuel, duration-based, or module-based timeout. Note that20// the module-based timeout is implemented with wasm-smith's21// `ensure_termination` option.22let timeout = if u.arbitrary()? {23config.generate_timeout(u)?24} else {25Timeout::None26};2728Ok(InstantiateInput { config, timeout })29}30}3132fn execute(33module: &[u8],34known_valid: KnownValid,35mut input: InstantiateInput,36u: &mut Unstructured<'_>,37) -> Result<()> {38let timeout = match input.timeout {39// If the input module isn't a "known valid" module then it can't be40// relied on self-regulating itself, so force a timeout via epochs/fuel41// in the configuration.42Timeout::None if known_valid == KnownValid::No => input.config.generate_timeout(u)?,43other => other,44};45instantiate(module, known_valid, &input.config, timeout);46Ok(())47}4849fn gen_module(50input: &mut InstantiateInput,51u: &mut Unstructured<'_>,52) -> Result<(Vec<u8>, KnownValid)> {53// With a small-ish chance take raw fuzz input and put it in the module to54// stress module compilation/validation. In such a situation we can't use55// `ensure_termination` in wasm-smith so list the timeout as `None` to time56// out via epochs or Wasmtime-level fuel.57//58// Otherwise though if no timeout is configured use wasm-smith fuel to59// ensure termination.60let allow_invalid_funcs = u.ratio(1, 10)?;6162let default_fuel = if allow_invalid_funcs {63input.config.module_config.config.allow_invalid_funcs = true;64input.timeout = Timeout::None;65None66} else if let Timeout::None = input.timeout {67Some(1000)68} else {69None70};71let module = input.config.generate(u, default_fuel)?;72let known_valid = if allow_invalid_funcs {73KnownValid::No74} else {75KnownValid::Yes76};77Ok((module.to_bytes(), known_valid))78}798081