1 //! Compile arbitrary bytes from the fuzzer as if they were Wasm, checking that
2 //! compilation is deterministic.
3 //!
4 //! Also use `wasm-mutate` to mutate the fuzz inputs.
5 
6 #![no_main]
7 
8 use libfuzzer_sys::{fuzz_mutator, fuzz_target};
9 use wasmtime::{Config, Engine, Module, Result};
10 
create_engine() -> Engine11 fn create_engine() -> Engine {
12     let mut config = Config::default();
13     // Safety: the Cranelift option `regalloc_checker` does not alter
14     // the generated code at all; it only does extra checking after
15     // compilation.
16     unsafe {
17         config.cranelift_flag_enable("regalloc_checker");
18     }
19     Engine::new(&config).expect("Could not construct Engine")
20 }
21 
compile_and_serialize(engine: &Engine, wasm: &[u8]) -> Result<Vec<u8>>22 fn compile_and_serialize(engine: &Engine, wasm: &[u8]) -> Result<Vec<u8>> {
23     let module = Module::new(&engine, wasm)?;
24     module.serialize()
25 }
26 
27 fuzz_target!(|data: &[u8]| {
28     let engine = create_engine();
29     wasmtime_fuzzing::oracles::log_wasm(data);
30 
31     if let Ok(bytes1) = compile_and_serialize(&engine, data) {
32         let bytes2 = compile_and_serialize(&engine, data)
33             .expect("successfully compiled once, should successfully compile again");
34 
35         // NB: Don't use `assert_eq!` here because it prints out the LHS and RHS
36         // to stderr on failure, which isn't helpful here since it is just a
37         // huge serialized binary.
38         assert!(bytes1 == bytes2, "Wasm compilation should be deterministic");
39     }
40 });
41 
42 fuzz_mutator!(|data: &mut [u8], size: usize, max_size: usize, seed: u32| {
43     // Half of the time use libfuzzer's built in mutators, and the other half of
44     // the time use `wasm-mutate`.
45     if seed.count_ones() % 2 == 0 {
46         libfuzzer_sys::fuzzer_mutate(data, size, max_size)
47     } else {
48         wasmtime_fuzzing::mutators::wasm_mutate(
49             data,
50             size,
51             max_size,
52             seed,
53             libfuzzer_sys::fuzzer_mutate,
54         )
55     }
56 });
57