File: compile.rs

package info (click to toggle)
rust-wasmtime 27.0.0%2Bdfsg-3
  • links: PTS, VCS
  • area: main
  • in suites: forky
  • size: 53,064 kB
  • sloc: ansic: 4,020; sh: 562; javascript: 542; cpp: 254; asm: 175; ml: 96; makefile: 55
file content (56 lines) | stat: -rw-r--r-- 1,890 bytes parent folder | download | duplicates (6)
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
//! Compile arbitrary bytes from the fuzzer as if they were Wasm, checking that
//! compilation is deterministic.
//!
//! Also use `wasm-mutate` to mutate the fuzz inputs.

#![no_main]

use libfuzzer_sys::{fuzz_mutator, fuzz_target};
use wasmtime::{Config, Engine, Module, Result};

fn create_engine() -> Engine {
    let mut config = Config::default();
    // Safety: the Cranelift option `regalloc_checker` does not alter
    // the generated code at all; it only does extra checking after
    // compilation.
    unsafe {
        config.cranelift_flag_enable("regalloc_checker");
    }
    Engine::new(&config).expect("Could not construct Engine")
}

fn compile_and_serialize(engine: &Engine, wasm: &[u8]) -> Result<Vec<u8>> {
    let module = Module::new(&engine, wasm)?;
    module.serialize()
}

fuzz_target!(|data: &[u8]| {
    let engine = create_engine();
    wasmtime_fuzzing::oracles::log_wasm(data);

    if let Ok(bytes1) = compile_and_serialize(&engine, data) {
        let bytes2 = compile_and_serialize(&engine, data)
            .expect("successfully compiled once, should successfully compile again");

        // NB: Don't use `assert_eq!` here because it prints out the LHS and RHS
        // to stderr on failure, which isn't helpful here since it is just a
        // huge serialized binary.
        assert!(bytes1 == bytes2, "Wasm compilation should be deterministic");
    }
});

fuzz_mutator!(|data: &mut [u8], size: usize, max_size: usize, seed: u32| {
    // Half of the time use libfuzzer's built in mutators, and the other half of
    // the time use `wasm-mutate`.
    if seed.count_ones() % 2 == 0 {
        libfuzzer_sys::fuzzer_mutate(data, size, max_size)
    } else {
        wasmtime_fuzzing::mutators::wasm_mutate(
            data,
            size,
            max_size,
            seed,
            libfuzzer_sys::fuzzer_mutate,
        )
    }
});