Path: blob/main/crates/environ/fuzz/fuzz_targets/fact-valid-module.rs
3101 views
//! A simple fuzzer for FACT1//!2//! This is an intentionally small fuzzer which is intended to only really be3//! used during the development of FACT itself when generating adapter modules.4//! This creates arbitrary adapter signatures and then generates the required5//! trampoline for that adapter ensuring that the final output wasm module is a6//! valid wasm module. This doesn't actually validate anything about the7//! correctness of the trampoline, only that it's valid wasm.89#![no_main]1011use arbitrary::Unstructured;12use libfuzzer_sys::fuzz_target;13use wasmtime_environ::{ScopeVec, Tunables, component::*};14use wasmtime_test_util::component_fuzz::{MAX_TYPE_DEPTH, TestCase, Type};1516const TYPE_COUNT: usize = 50;1718#[derive(Debug)]19struct GenAdapter<'a> {20test: TestCase<'a>,21// TODO: Add these arbitrary options and thread them into22// `Declarations::make_component`, or alternatively pass an `Unstructured`23// into that method to make arbitrary choices for these things.24//25// post_return: bool,26// lift_memory64: bool,27// lower_memory64: bool,28}2930fuzz_target!(|data: &[u8]| {31let _ = target(data);32});3334fn target(data: &[u8]) -> arbitrary::Result<()> {35drop(env_logger::try_init());3637let mut u = Unstructured::new(data);3839// First generate a set of type to select from.40let mut type_fuel = 1000;41let mut types = Vec::new();42for _ in 0..u.int_in_range(1..=TYPE_COUNT)? {43// Only discount fuel if the generation was successful,44// otherwise we'll get more random data and try again.45types.push(Type::generate(&mut u, MAX_TYPE_DEPTH, &mut type_fuel)?);46}4748// Next generate a static API test case driven by the above types.49let test = TestCase::generate(&types, &mut u)?;50let adapter = GenAdapter { test };5152let wat_decls = adapter.test.declarations();53let component = wat_decls.make_component();54let component = wat::parse_str(&component).unwrap();5556let mut tunables = Tunables::default_host();57tunables.debug_adapter_modules = u.arbitrary()?;5859let mut validator = wasmparser::Validator::new_with_features(wasmparser::WasmFeatures::all());60let mut component_types = ComponentTypesBuilder::new(&validator);61let adapters = ScopeVec::new();6263Translator::new(&tunables, &mut validator, &mut component_types, &adapters)64.translate(&component)65.expect("should never generate an invalid component");6667let adapters = adapters.into_iter();68assert!(adapters.len() >= 1);69for wasm in adapters {70validator.reset();71if let Err(err) = validator.validate_all(&wasm) {72eprintln!("invalid wasm module: {err:?}");73eprintln!("adapter: {adapter:?}");74std::fs::write("invalid.wasm", &wasm).unwrap();75match wasmprinter::print_bytes(&wasm) {76Ok(s) => std::fs::write("invalid.wat", &s).unwrap(),77Err(_) => drop(std::fs::remove_file("invalid.wat")),78}79panic!("invalid adapter: {err:?}")80}81}8283Ok(())84}858687