Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
bytecodealliance
GitHub Repository: bytecodealliance/wasmtime
Path: blob/main/fuzz/fuzz_targets/table_ops.rs
1690 views
1
#![no_main]
2
3
use libfuzzer_sys::arbitrary::{Arbitrary, Unstructured};
4
use libfuzzer_sys::{fuzz_mutator, fuzz_target, fuzzer_mutate};
5
use mutatis::Session;
6
use postcard::{from_bytes, to_slice};
7
use rand::{Rng, SeedableRng};
8
use wasmtime_fuzzing::generators::table_ops::TableOps;
9
use wasmtime_fuzzing::oracles::table_ops;
10
11
fuzz_target!(|data: &[u8]| {
12
let Ok((seed, ops)) = postcard::from_bytes::<(u64, TableOps)>(data) else {
13
return;
14
};
15
16
let mut buf = [0u8; 1024];
17
let mut rng = rand::rngs::StdRng::seed_from_u64(seed);
18
rng.fill(&mut buf);
19
20
let u = Unstructured::new(&buf);
21
let Ok(config) = wasmtime_fuzzing::generators::Config::arbitrary_take_rest(u) else {
22
return;
23
};
24
25
let _ = table_ops(config, ops);
26
});
27
28
fuzz_mutator!(|data: &mut [u8], size: usize, max_size: usize, seed: u32| {
29
let _ = env_logger::try_init();
30
31
// With probability of about 1/8, use default mutator
32
if seed.count_ones() % 8 == 0 {
33
return fuzzer_mutate(data, size, max_size);
34
}
35
36
// Try to decode using postcard; fallback to default input on failure
37
let mut tuple: (u64, TableOps) = from_bytes(&data[..size]).ok().unwrap_or_default();
38
39
let mut session = Session::new().seed(seed.into()).shrink(max_size < size);
40
41
if session.mutate(&mut tuple).is_ok() {
42
loop {
43
if let Ok(encoded) = to_slice(&tuple, data) {
44
return encoded.len();
45
}
46
47
// Attempt to shrink ops if encoding fails (e.g., buffer too small)
48
if tuple.1.pop() {
49
continue;
50
}
51
52
break;
53
}
54
}
55
56
// Fallback to default libfuzzer mutator
57
fuzzer_mutate(data, size, max_size)
58
});
59
60