Coverage Report

Created: 2025-12-04 07:01

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/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
}