Executes a "single module fuzzer" given the raw `input` from libfuzzer. This will use the `input` to generate `T`, some configuration, which is then used by `gen_module` to generate a WebAssembly module. The module is then passed to `run` along with the configuration and remaining data that can be used as fuzz input. The main purpose of this function is to handle when `input` is actually a WebAs
(
input: &'a [u8],
run: fn(&[u8], KnownValid, T, &mut Unstructured<'a>) -> Result<U>,
gen_module: fn(&mut T, &mut Unstructured<'a>) -> Result<(Vec<u8>, KnownValid)>,
)
| 94 | /// we're still interested in the historical coverage of the original wasm |
| 95 | /// module. |
| 96 | pub fn execute<'a, T, U>( |
| 97 | input: &'a [u8], |
| 98 | run: fn(&[u8], KnownValid, T, &mut Unstructured<'a>) -> Result<U>, |
| 99 | gen_module: fn(&mut T, &mut Unstructured<'a>) -> Result<(Vec<u8>, KnownValid)>, |
| 100 | ) -> Result<U> |
| 101 | where |
| 102 | T: Arbitrary<'a>, |
| 103 | { |
| 104 | let (fuzz_data, module_in_input) = match extract_fuzz_input(input) { |
| 105 | Ok(input) => { |
| 106 | log::debug!("fuzz input was a valid module with trailing custom section"); |
| 107 | (input.fuzz_data, Some(input.module)) |
| 108 | } |
| 109 | Err(e) => { |
| 110 | log::debug!("fuzz input not a valid module: {e:?}"); |
| 111 | (input, None) |
| 112 | } |
| 113 | }; |
| 114 | let mut u = Unstructured::new(fuzz_data); |
| 115 | let mut config = u.arbitrary()?; |
| 116 | let (generated, known_valid) = gen_module(&mut config, &mut u)?; |
| 117 | let module = module_in_input.unwrap_or(&generated); |
| 118 | if let Ok(file) = std::env::var("WRITE_FUZZ_INPUT_TO") { |
| 119 | std::fs::write(file, encode_module(&module, &fuzz_data)).unwrap(); |
| 120 | } |
| 121 | let known_valid = if module_in_input.is_some() { |
| 122 | KnownValid::No |
| 123 | } else { |
| 124 | known_valid |
| 125 | }; |
| 126 | run(module, known_valid, config, &mut u) |
| 127 | } |
| 128 | |
| 129 | /// Used as part of `execute` above to determine whether a module is known to |
| 130 | /// be valid ahead of time. |