Skip to content

Commit

Permalink
implement fuzzing for component types (#4537)
Browse files Browse the repository at this point in the history
This addresses #4307.

For the static API we generate 100 arbitrary test cases at build time, each of
which includes 0-5 parameter types, a result type, and a WAT fragment containing
an imported function and an exported function.  The exported function calls the
imported function, which is implemented by the host.  At runtime, the fuzz test
selects a test case at random and feeds it zero or more sets of arbitrary
parameters and results, checking that values which flow host-to-guest and
guest-to-host make the transition unchanged.

The fuzz test for the dynamic API follows a similar pattern, the only difference
being that test cases are generated at runtime.

Signed-off-by: Joel Dice <[email protected]>
  • Loading branch information
dicej authored Aug 4, 2022
1 parent ad223c5 commit ed8908e
Show file tree
Hide file tree
Showing 29 changed files with 1,964 additions and 267 deletions.
33 changes: 33 additions & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

8 changes: 7 additions & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,8 @@ once_cell = "1.9.0"
rayon = "1.5.0"
component-macro-test = { path = "crates/misc/component-macro-test" }
wasmtime-wast = { path = "crates/wast", version = "=0.40.0", features = ['component-model'] }
component-test-util = { path = "crates/misc/component-test-util" }
wasmtime-component-util = { path = "crates/component-util" }

[target.'cfg(windows)'.dev-dependencies]
windows-sys = { version = "0.36.0", features = ["Win32_System_Memory"] }
Expand Down Expand Up @@ -110,7 +112,11 @@ memory-init-cow = ["wasmtime/memory-init-cow", "wasmtime-cli-flags/memory-init-c
pooling-allocator = ["wasmtime/pooling-allocator", "wasmtime-cli-flags/pooling-allocator"]
all-arch = ["wasmtime/all-arch"]
posix-signals-on-macos = ["wasmtime/posix-signals-on-macos"]
component-model = ["wasmtime/component-model", "wasmtime-wast/component-model", "wasmtime-cli-flags/component-model"]
component-model = [
"wasmtime/component-model",
"wasmtime-wast/component-model",
"wasmtime-cli-flags/component-model"
]

# Stub feature that does nothing, for Cargo-features compatibility: the new
# backend is the default now.
Expand Down
2 changes: 1 addition & 1 deletion build.rs
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ fn main() -> anyhow::Result<()> {
} else {
println!(
"cargo:warning=The spec testsuite is disabled. To enable, run `git submodule \
update --remote`."
update --remote`."
);
}
Ok(())
Expand Down
5 changes: 4 additions & 1 deletion crates/component-macro/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -885,7 +885,10 @@ impl Expander for ComponentTypeExpander {
const SIZE32: usize = {
let mut size = 0;
#sizes
#internal::align_to(#discriminant_size as usize, Self::ALIGN32) + size
#internal::align_to(
#internal::align_to(#discriminant_size as usize, Self::ALIGN32) + size,
Self::ALIGN32
)
};

const ALIGN32: u32 = {
Expand Down
59 changes: 59 additions & 0 deletions crates/component-util/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -77,3 +77,62 @@ impl FlagsSize {
fn ceiling_divide(n: usize, d: usize) -> usize {
(n + d - 1) / d
}

/// A simple bump allocator which can be used with modules
pub const REALLOC_AND_FREE: &str = r#"
(global $last (mut i32) (i32.const 8))
(func $realloc (export "realloc")
(param $old_ptr i32)
(param $old_size i32)
(param $align i32)
(param $new_size i32)
(result i32)
;; Test if the old pointer is non-null
local.get $old_ptr
if
;; If the old size is bigger than the new size then
;; this is a shrink and transparently allow it
local.get $old_size
local.get $new_size
i32.gt_u
if
local.get $old_ptr
return
end
;; ... otherwise this is unimplemented
unreachable
end
;; align up `$last`
(global.set $last
(i32.and
(i32.add
(global.get $last)
(i32.add
(local.get $align)
(i32.const -1)))
(i32.xor
(i32.add
(local.get $align)
(i32.const -1))
(i32.const -1))))
;; save the current value of `$last` as the return value
global.get $last
;; ensure anything necessary is set to valid data by spraying a bit
;; pattern that is invalid
global.get $last
i32.const 0xde
local.get $new_size
memory.fill
;; bump our pointer
(global.set $last
(i32.add
(global.get $last)
(local.get $new_size)))
)
"#;
3 changes: 2 additions & 1 deletion crates/environ/fuzz/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ libfuzzer-sys = "0.4"
wasmparser = "0.88.0"
wasmprinter = "0.2.37"
wasmtime-environ = { path = ".." }
component-fuzz-util = { path = "../../misc/component-fuzz-util", optional = true }

[[bin]]
name = "fact-valid-module"
Expand All @@ -24,4 +25,4 @@ doc = false
required-features = ["component-model"]

[features]
component-model = ["wasmtime-environ/component-model"]
component-model = ["wasmtime-environ/component-model", "dep:component-fuzz-util"]
Loading

0 comments on commit ed8908e

Please sign in to comment.