Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
bytecodealliance
GitHub Repository: bytecodealliance/wasmtime
Path: blob/main/crates/environ/fuzz/fuzz_targets/fact-valid-module.rs
3101 views
1
//! A simple fuzzer for FACT
2
//!
3
//! This is an intentionally small fuzzer which is intended to only really be
4
//! used during the development of FACT itself when generating adapter modules.
5
//! This creates arbitrary adapter signatures and then generates the required
6
//! trampoline for that adapter ensuring that the final output wasm module is a
7
//! valid wasm module. This doesn't actually validate anything about the
8
//! correctness of the trampoline, only that it's valid wasm.
9
10
#![no_main]
11
12
use arbitrary::Unstructured;
13
use libfuzzer_sys::fuzz_target;
14
use wasmtime_environ::{ScopeVec, Tunables, component::*};
15
use wasmtime_test_util::component_fuzz::{MAX_TYPE_DEPTH, TestCase, Type};
16
17
const TYPE_COUNT: usize = 50;
18
19
#[derive(Debug)]
20
struct GenAdapter<'a> {
21
test: TestCase<'a>,
22
// TODO: Add these arbitrary options and thread them into
23
// `Declarations::make_component`, or alternatively pass an `Unstructured`
24
// into that method to make arbitrary choices for these things.
25
//
26
// post_return: bool,
27
// lift_memory64: bool,
28
// lower_memory64: bool,
29
}
30
31
fuzz_target!(|data: &[u8]| {
32
let _ = target(data);
33
});
34
35
fn target(data: &[u8]) -> arbitrary::Result<()> {
36
drop(env_logger::try_init());
37
38
let mut u = Unstructured::new(data);
39
40
// First generate a set of type to select from.
41
let mut type_fuel = 1000;
42
let mut types = Vec::new();
43
for _ in 0..u.int_in_range(1..=TYPE_COUNT)? {
44
// Only discount fuel if the generation was successful,
45
// otherwise we'll get more random data and try again.
46
types.push(Type::generate(&mut u, MAX_TYPE_DEPTH, &mut type_fuel)?);
47
}
48
49
// Next generate a static API test case driven by the above types.
50
let test = TestCase::generate(&types, &mut u)?;
51
let adapter = GenAdapter { test };
52
53
let wat_decls = adapter.test.declarations();
54
let component = wat_decls.make_component();
55
let component = wat::parse_str(&component).unwrap();
56
57
let mut tunables = Tunables::default_host();
58
tunables.debug_adapter_modules = u.arbitrary()?;
59
60
let mut validator = wasmparser::Validator::new_with_features(wasmparser::WasmFeatures::all());
61
let mut component_types = ComponentTypesBuilder::new(&validator);
62
let adapters = ScopeVec::new();
63
64
Translator::new(&tunables, &mut validator, &mut component_types, &adapters)
65
.translate(&component)
66
.expect("should never generate an invalid component");
67
68
let adapters = adapters.into_iter();
69
assert!(adapters.len() >= 1);
70
for wasm in adapters {
71
validator.reset();
72
if let Err(err) = validator.validate_all(&wasm) {
73
eprintln!("invalid wasm module: {err:?}");
74
eprintln!("adapter: {adapter:?}");
75
std::fs::write("invalid.wasm", &wasm).unwrap();
76
match wasmprinter::print_bytes(&wasm) {
77
Ok(s) => std::fs::write("invalid.wat", &s).unwrap(),
78
Err(_) => drop(std::fs::remove_file("invalid.wat")),
79
}
80
panic!("invalid adapter: {err:?}")
81
}
82
}
83
84
Ok(())
85
}
86
87