MCPcopy Create free account
hub / github.com/bytecodealliance/wasmtime / wasm_mutate

Function wasm_mutate

crates/fuzzing/src/mutators.rs:14–100  ·  view source on GitHub ↗

Use [`wasm-mutate`][wasm-mutate] to mutate a fuzz input. [wasm-mutate]: https://github.com/bytecodealliance/wasm-tools/tree/main/crates/wasm-mutate

(
    data: &mut [u8],
    size: usize,
    max_size: usize,
    seed: u32,
    libfuzzer_mutate: fn(data: &mut [u8], size: usize, max_size: usize) -> usize,
)

Source from the content-addressed store, hash-verified

12///
13/// [wasm-mutate]: https://github.com/bytecodealliance/wasm-tools/tree/main/crates/wasm-mutate
14pub fn wasm_mutate(
15 data: &mut [u8],
16 size: usize,
17 max_size: usize,
18 seed: u32,
19 libfuzzer_mutate: fn(data: &mut [u8], size: usize, max_size: usize) -> usize,
20) -> usize {
21 const MUTATION_FUEL: u64 = 100;
22 const MUTATION_ITERS: usize = 100;
23
24 let wasm = &data[..size];
25
26 if wasmparser::validate(wasm).is_ok() {
27 let mut wasm_mutate = wasm_mutate::WasmMutate::default();
28 wasm_mutate
29 .seed(seed.into())
30 .fuel(MUTATION_FUEL)
31 .reduce(max_size < size)
32 .raw_mutate_func(Some(Arc::new(move |data, max_size| {
33 let len = data.len();
34
35 // The given max could be very large, so clamp it to no more
36 // than `len * 2` in any single, given mutation. This way we
37 // don't over-allocate a bunch of space.
38 let max_size = std::cmp::min(max_size, len * 2);
39 // Also, the max must always be greater than zero (`libfuzzer`
40 // asserts this).
41 let max_size = std::cmp::max(max_size, 1);
42
43 // Make sure we have capacity in case `libfuzzer` decides to
44 // grow this data.
45 if max_size > len {
46 data.resize(max_size, 0);
47 }
48
49 // Finally, have `libfuzzer` mutate the data!
50 let new_len = libfuzzer_mutate(data, len, max_size);
51
52 // Resize the data to the mutated size, releasing any extra
53 // capacity that we don't need anymore.
54 data.resize(new_len, 0);
55 data.shrink_to_fit();
56
57 Ok(())
58 })));
59
60 let wasm = wasm.to_vec();
61 let mutations = wasm_mutate.run(&wasm);
62 if let Ok(mutations) = mutations {
63 for mutation in mutations.take(MUTATION_ITERS) {
64 if let Ok(mutated_wasm) = mutation {
65 if mutated_wasm.len() <= max_size {
66 data[..mutated_wasm.len()].copy_from_slice(&mutated_wasm);
67 return mutated_wasm.len();
68 }
69 }
70 }
71 }

Callers

nothing calls this directly

Calls 14

maxFunction · 0.85
OkFunction · 0.85
is_okMethod · 0.80
seedMethod · 0.80
validateFunction · 0.50
newFunction · 0.50
lenMethod · 0.45
resizeMethod · 0.45
shrink_to_fitMethod · 0.45
to_vecMethod · 0.45
runMethod · 0.45
takeMethod · 0.45

Tested by

no test coverage detected