File: instantiate-many.rs

package info (click to toggle)
rust-wasmtime 28.0.1%2Bdfsg-2
  • links: PTS, VCS
  • area: main
  • in suites:
  • size: 54,116 kB
  • sloc: ansic: 4,071; sh: 567; javascript: 548; cpp: 280; asm: 175; ml: 96; makefile: 55
file content (63 lines) | stat: -rw-r--r-- 2,593 bytes parent folder | download | duplicates (5)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
//! This fuzz target is used to test multiple concurrent instantiations from
//! multiple modules.

#![no_main]

use libfuzzer_sys::arbitrary::{Result, Unstructured};
use libfuzzer_sys::fuzz_target;
use wasmtime_fuzzing::single_module_fuzzer::KnownValid;
use wasmtime_fuzzing::{generators, oracles};

const MAX_MODULES: usize = 5;

fuzz_target!(|data: &[u8]| {
    // errors in `run` have to do with not enough input in `data`, which we
    // ignore here since it doesn't affect how we'd like to fuzz.
    let _ = execute_one(data);
});

fn execute_one(data: &[u8]) -> Result<()> {
    let mut u = Unstructured::new(data);
    let mut config: generators::Config = u.arbitrary()?;

    // Don't generate start functions
    // No wasm code execution is necessary for this fuzz target and thus we don't
    // use timeouts or ensure that the generated wasm code will terminate.
    config.module_config.config.allow_start_export = false;

    // Wasm linear memories take roughly ~8gb of virtual address space. Down
    // below we could instantiate up to 300 modules. Conservatively estimating
    // that we have 46 bits of address space to work with (technically 48 on
    // x86_64, but take some out for kernel stuff and some for asan stuff) that
    // gives us a budget of ~27 memories per instance. Reduce that a bit further
    // and make sure that no instance has more than 10 linear memories to ensure
    // that even if the maximum were created it should still fit in the linear
    // address space.
    config.module_config.config.max_memories = config.module_config.config.max_memories.min(10);

    // Create the modules to instantiate
    let modules = (0..u.int_in_range(1..=MAX_MODULES)?)
        .map(|_| Ok(config.generate(&mut u, None)?.to_bytes()))
        .collect::<Result<Vec<_>>>()?;

    let max_instances = match &config.wasmtime.strategy {
        generators::InstanceAllocationStrategy::OnDemand => u.int_in_range(1..=100)?,
        generators::InstanceAllocationStrategy::Pooling(config) => config.total_core_instances,
    };

    // Front-load with instantiation commands
    let mut commands: Vec<oracles::Command> = (0..u.int_in_range(1..=max_instances)?)
        .map(|_| Ok(oracles::Command::Instantiate(u.arbitrary()?)))
        .collect::<Result<_>>()?;

    // Then add some more arbitrary commands
    commands.extend(
        (0..u.int_in_range(0..=2 * max_instances)?)
            .map(|_| u.arbitrary())
            .collect::<Result<Vec<_>>>()?,
    );

    oracles::instantiate_many(&modules, KnownValid::Yes, &config, &commands);

    Ok(())
}