Merge pull request #1189 from fitzgen/fuzzing-api-calls-timeouts

Fuzzing api calls timeouts
This commit is contained in:
Nick Fitzgerald
2020-02-28 16:30:04 -08:00
committed by GitHub
5 changed files with 52 additions and 20 deletions

23
Cargo.lock generated
View File

@@ -41,15 +41,9 @@ checksum = "7825f6833612eb2414095684fcf6c635becf3ce97fe48cf6421321e93bfbd53c"
[[package]]
name = "arbitrary"
version = "0.2.0"
version = "0.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "64cf76cb6e2222ed0ea86b2b0ee2f71c96ec6edd5af42e84d59160e91b836ec4"
[[package]]
name = "arbitrary"
version = "0.3.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "491d5e42b1a073ff1fc1e0a02744b3f8bee9cf4bfd552053cac36c64b879795d"
checksum = "16971f2f0ce65c5cf2a1546cc6a0af102ecb11e265ddaa9433fb3e5bfdf676a4"
dependencies = [
"derive_arbitrary",
]
@@ -521,9 +515,9 @@ dependencies = [
[[package]]
name = "derive_arbitrary"
version = "0.3.3"
version = "0.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "dab2f0544254a47cabc58956cc7ebda74c3b796bb2761e3fe8f29fdde632ad95"
checksum = "caedd6a71b6d00bdc458ec8ffbfd12689c1ee7ffa69ad9933310aaf2f08f18d8"
dependencies = [
"proc-macro2",
"syn",
@@ -955,11 +949,11 @@ checksum = "eb147597cdf94ed43ab7a9038716637d2d1bf2bc571da995d0028dec06bd3018"
[[package]]
name = "libfuzzer-sys"
version = "0.2.1"
version = "0.3.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3e969cd2be7a2aae0acbbe205da49134148db2287fb45a811bf441ed72f09a35"
checksum = "fb789afcc589a08928d1e466087445ab740a0f70a2ee23d9349a0e3723d65e1b"
dependencies = [
"arbitrary 0.3.3",
"arbitrary",
"cc",
]
@@ -2121,7 +2115,6 @@ dependencies = [
name = "wasmtime-fuzz"
version = "0.12.0"
dependencies = [
"arbitrary 0.2.0",
"cranelift-codegen",
"cranelift-reader",
"cranelift-wasm",
@@ -2136,7 +2129,7 @@ name = "wasmtime-fuzzing"
version = "0.12.0"
dependencies = [
"anyhow",
"arbitrary 0.3.3",
"arbitrary",
"binaryen",
"env_logger 0.7.1",
"log",

View File

@@ -8,7 +8,7 @@ version = "0.12.0"
[dependencies]
anyhow = "1.0.22"
arbitrary = { version = "0.3.2", features = ["derive"] }
arbitrary = { version = "0.4.0", features = ["derive"] }
binaryen = "0.10.0"
env_logger = "0.7.1"
log = "0.4.8"

View File

@@ -44,6 +44,10 @@ impl Arbitrary for WasmOptTtf {
let wasm = module.write();
Ok(WasmOptTtf { wasm })
}
fn size_hint(depth: usize) -> (usize, Option<usize>) {
<Vec<u8> as Arbitrary>::size_hint(depth)
}
}
/// A description of configuration options that we should do differential

View File

@@ -48,12 +48,20 @@ use ApiCall::*;
#[derive(Default)]
struct Scope {
id_counter: usize,
predicted_rss: usize,
/// Map from a module id to the predicted amount of rss it will take to
/// instantiate.
modules: BTreeMap<usize, usize>,
/// Map from an instance id to the amount of rss it's expected to be using.
instances: BTreeMap<usize, usize>,
/// The rough predicted maximum RSS of executing all of our generated API
/// calls thus far.
predicted_rss: usize,
/// The number of calls of an exported function from an instance.
num_export_calls: usize,
}
impl Scope {
@@ -83,6 +91,11 @@ impl Arbitrary for ApiCalls {
let mut scope = Scope::default();
let max_rss = 1 << 30; // 1GB
// Calling an exported function of a `wasm-opt -ttf` module tends to
// take about 20ms. Limit their number to 100, or ~2s, so that we don't
// get too close to our 3s timeout.
let max_export_calls = 100;
for _ in 0..input.arbitrary_len::<ApiCall>()? {
let mut choices: Vec<fn(_, &mut Scope) -> arbitrary::Result<ApiCall>> = vec![];
@@ -122,8 +135,12 @@ impl Arbitrary for ApiCalls {
Ok(InstanceDrop { id })
});
}
if swarm.call_exported_func && !scope.instances.is_empty() {
if swarm.call_exported_func
&& scope.num_export_calls < max_export_calls
&& !scope.instances.is_empty()
{
choices.push(|input, scope| {
scope.num_export_calls += 1;
let instances: Vec<_> = scope.instances.keys().collect();
let instance = **input.choose(&instances)?;
let nth = usize::arbitrary(input)?;
@@ -140,6 +157,25 @@ impl Arbitrary for ApiCalls {
Ok(ApiCalls { calls })
}
fn size_hint(depth: usize) -> (usize, Option<usize>) {
arbitrary::size_hint::recursion_guard(depth, |depth| {
arbitrary::size_hint::or(
// This is the stuff we unconditionally need, which affects the
// minimum size.
arbitrary::size_hint::and(
<Swarm as Arbitrary>::size_hint(depth),
// `arbitrary_config` uses two bools when
// `swarm.config_debug_info` is true.
<(bool, bool) as Arbitrary>::size_hint(depth),
),
// We can generate arbitrary `WasmOptTtf` instances, which have
// no upper bound on the number of bytes they consume. This sets
// the upper bound to `None`.
<super::WasmOptTtf as Arbitrary>::size_hint(depth),
)
})
}
}
fn arbitrary_config(

View File

@@ -9,11 +9,10 @@ publish = false
cargo-fuzz = true
[dependencies]
arbitrary = "0.2.0"
cranelift-codegen = { path = "../cranelift/codegen" }
cranelift-reader = { path = "../cranelift/reader" }
cranelift-wasm = { path = "../cranelift/wasm" }
libfuzzer-sys = "0.2.1"
libfuzzer-sys = "0.3.1"
target-lexicon = "0.10"
wasmtime = { path = "../crates/api" }
wasmtime-fuzzing = { path = "../crates/fuzzing" }