1 #![no_main] 2 3 use libfuzzer_sys::arbitrary::{Result, Unstructured}; 4 use libfuzzer_sys::fuzz_target; 5 use wasmtime_fuzzing::{generators, oracles}; 6 7 fuzz_target!(|data: &[u8]| { 8 // errors in `run` have to do with not enough input in `data`, which we 9 // ignore here since it doesn't affect how we'd like to fuzz. 10 let _ = run_one(data); 11 }); 12 run_one(data: &[u8]) -> Result<()>13fn run_one(data: &[u8]) -> Result<()> { 14 let mut u = Unstructured::new(data); 15 let mut config: generators::Config = u.arbitrary()?; 16 17 // Try to ensure imports/exports/etc are generated by adding one to the 18 // minimums/maximums. 19 config.module_config.config.min_types = 1; 20 config.module_config.config.max_types += 1; 21 config.module_config.config.min_imports = 1; 22 config.module_config.config.max_imports += 1; 23 config.module_config.config.min_funcs = 1; 24 config.module_config.config.max_funcs += 1; 25 config.module_config.config.min_exports = 1; 26 config.module_config.config.max_exports += 1; 27 28 // Use the fuzz input to select an async strategy. 29 config.enable_async(&mut u)?; 30 31 let mut poll_amts = Vec::with_capacity(u.arbitrary_len::<u32>()?); 32 for _ in 0..poll_amts.capacity() { 33 poll_amts.push(u.int_in_range(0..=10_000)?); 34 } 35 let module = config.module_config.generate(&mut u, None)?; 36 oracles::call_async(&module.to_bytes(), &config, &poll_amts); 37 38 Ok(()) 39 } 40