/src/wasmtime/fuzz/fuzz_targets/instantiate-many.rs
Line | Count | Source |
1 | | //! This fuzz target is used to test multiple concurrent instantiations from |
2 | | //! multiple modules. |
3 | | |
4 | | #![no_main] |
5 | | |
6 | | use libfuzzer_sys::arbitrary::{Result, Unstructured}; |
7 | | use libfuzzer_sys::fuzz_target; |
8 | | use wasmtime_fuzzing::single_module_fuzzer::KnownValid; |
9 | | use wasmtime_fuzzing::{generators, oracles}; |
10 | | |
11 | | const MAX_MODULES: usize = 5; |
12 | | |
13 | | fuzz_target!(|data: &[u8]| { |
14 | | // errors in `run` have to do with not enough input in `data`, which we |
15 | | // ignore here since it doesn't affect how we'd like to fuzz. |
16 | | let _ = execute_one(data); |
17 | | }); |
18 | | |
19 | 11.0k | fn execute_one(data: &[u8]) -> Result<()> { |
20 | 11.0k | let mut u = Unstructured::new(data); |
21 | 11.0k | let mut config: generators::Config = u.arbitrary()?; |
22 | | |
23 | | // Don't generate start functions |
24 | | // No wasm code execution is necessary for this fuzz target and thus we don't |
25 | | // use timeouts or ensure that the generated wasm code will terminate. |
26 | 10.8k | config.module_config.config.allow_start_export = false; |
27 | | |
28 | | // Wasm linear memories take roughly ~8gb of virtual address space. Down |
29 | | // below we could instantiate up to 300 modules. Conservatively estimating |
30 | | // that we have 46 bits of address space to work with (technically 48 on |
31 | | // x86_64, but take some out for kernel stuff and some for asan stuff) that |
32 | | // gives us a budget of ~27 memories per instance. Reduce that a bit further |
33 | | // and make sure that no instance has more than 10 linear memories to ensure |
34 | | // that even if the maximum were created it should still fit in the linear |
35 | | // address space. |
36 | 10.8k | config.module_config.config.max_memories = config.module_config.config.max_memories.min(10); |
37 | | |
38 | | // Create the modules to instantiate |
39 | 10.8k | let modules = (0..u.int_in_range(1..=MAX_MODULES)?) |
40 | 31.7k | .map(|_| Ok(config.generate(&mut u, None)?.to_bytes())) |
41 | 10.8k | .collect::<Result<Vec<_>>>()?; |
42 | | |
43 | 10.7k | let max_instances = match &config.wasmtime.strategy { |
44 | 8.82k | generators::InstanceAllocationStrategy::OnDemand => u.int_in_range(1..=100)?, |
45 | 1.94k | generators::InstanceAllocationStrategy::Pooling(config) => config.total_core_instances, |
46 | | }; |
47 | | |
48 | | // Front-load with instantiation commands |
49 | 10.7k | let mut commands: Vec<oracles::Command> = (0..u.int_in_range(1..=max_instances)?) |
50 | 91.0k | .map(|_| Ok(oracles::Command::Instantiate(u.arbitrary()?))) |
51 | 10.7k | .collect::<Result<_>>()?; |
52 | | |
53 | | // Then add some more arbitrary commands |
54 | 10.7k | commands.extend( |
55 | 10.7k | (0..u.int_in_range(0..=2 * max_instances)?) |
56 | 117k | .map(|_| u.arbitrary()) |
57 | 10.7k | .collect::<Result<Vec<_>>>()?, |
58 | | ); |
59 | | |
60 | 10.7k | oracles::instantiate_many(&modules, KnownValid::Yes, &config, &commands); |
61 | | |
62 | 10.7k | Ok(()) |
63 | 11.0k | } |