Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add differential fuzzing against wasmi (a Wasm interpreter). #2453

Merged
merged 1 commit into from
Dec 2, 2020

Conversation

cfallin
Copy link
Member

@cfallin cfallin commented Nov 25, 2020

This PR adds a new fuzz target, differential_wasmi, that runs a
Cranelift-based Wasm backend alongside a simple third-party Wasm
interpeter crate (wasmi). The fuzzing runs the first function in a
given module to completion on each side, and then diffs the return value
and linear memory contents.

This strategy should provide end-to-end coverage including both the Wasm
translation to CLIF (which has seen some subtle and scary bugs at
times), the lowering from CLIF to VCode, the register allocation, and
the final code emission.

@github-actions github-actions bot added the fuzzing Issues related to our fuzzing infrastructure label Nov 25, 2020
@github-actions
Copy link

Subscribe to Label Action

cc @fitzgen

This issue or pull request has been labeled: "fuzzing"

Thus the following users have been cc'd because of the following labels:

  • fitzgen: fuzzing

To subscribe or unsubscribe from this label, edit the .github/subscribe-to-label.json configuration file.

Learn more.

Copy link
Member

@alexcrichton alexcrichton left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nice!

crates/fuzzing/src/oracles.rs Outdated Show resolved Hide resolved
crates/fuzzing/src/oracles.rs Outdated Show resolved Hide resolved
crates/fuzzing/src/oracles.rs Outdated Show resolved Hide resolved
Copy link
Member

@fitzgen fitzgen left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks good, thanks @cfallin!

Mostly just echoing what Alex had to say, but a couple inline comments nonetheless.

crates/fuzzing/src/oracles.rs Outdated Show resolved Hide resolved
crates/fuzzing/src/oracles.rs Outdated Show resolved Hide resolved
crates/fuzzing/src/oracles.rs Outdated Show resolved Hide resolved
crates/fuzzing/src/oracles.rs Outdated Show resolved Hide resolved
@cfallin cfallin force-pushed the differential-fuzz-interp branch 2 times, most recently from 0cf19cc to d0fe898 Compare December 2, 2020 00:23
@cfallin
Copy link
Member Author

cfallin commented Dec 2, 2020

Updated, thanks!

It turns out that wasmi doesn't canonicalize NaNs (wasmi-labs/wasmi#19) so I've disabled fuzzing of modules with FP ops for now. If it seems worthwhile, we can add a Config option to wasm-smith for that too, but fuzzing seems to be getting coverage pretty efficiently right now as I watch it run.

This fails the "publish" check because it's using a crate-source patch in the root Cargo.toml for wasm-smith; @fitzgen, would you mind publishing a new version to crates.io?

@fitzgen
Copy link
Member

fitzgen commented Dec 2, 2020

This fails the "publish" check because it's using a crate-source patch in the root Cargo.toml for wasm-smith; @fitzgen, would you mind publishing a new version to crates.io?

Sure thing.

@fitzgen
Copy link
Member

fitzgen commented Dec 2, 2020

Done!

@cfallin
Copy link
Member Author

cfallin commented Dec 2, 2020

Thanks! Updated.

I also just added an experimental_x64 feature flag to the fuzz crate so that we can fuzz the new backend.

cfallin added a commit to cfallin/wasmtime that referenced this pull request Dec 2, 2020
This issue was found while fuzzing the new backend (bytecodealliance#2453); I suspect
that it arises with the new backend because we can sink instructions
(e.g. loads or extends) in more interesting ways than before, but I'm
not entirely sure.

Test coverage will be via the fuzz corpus once bytecodealliance#2453 lands.
@github-actions github-actions bot added the wasmtime:api Related to the API of the `wasmtime` crate itself label Dec 2, 2020
@github-actions
Copy link

github-actions bot commented Dec 2, 2020

Subscribe to Label Action

cc @peterhuene

This issue or pull request has been labeled: "wasmtime:api"

Thus the following users have been cc'd because of the following labels:

  • peterhuene: wasmtime:api

To subscribe or unsubscribe from this label, edit the .github/subscribe-to-label.json configuration file.

Learn more.

cfallin added a commit to cfallin/wasmtime that referenced this pull request Dec 2, 2020
A dynamic heap address computation may create up to two conditional
branches: the usual bounds-check, but also (in some cases) an
offset-addition overflow check.

The x64 backend had reversed the condition code for this check,
resulting in an always-trapping execution for a valid offset. I'm
somewhat surprised this has existed so long, but I suppose the
particular conditions (large offset, small offset guard, dynamic heap)
have been somewhat rare in our testing so far.

Found via fuzzing in bytecodealliance#2453.
cfallin added a commit to cfallin/wasmtime that referenced this pull request Dec 2, 2020
- Sort by generated-code offset to maintain invariant and avoid gimli
  panic.
- Fix srcloc interaction with branch peephole optimization in
  MachBuffer: if a srcloc range overlaps with a branch that is
  truncated, remove that srcloc range.

These issues were found while fuzzing the new backend (bytecodealliance#2453); I suspect
that they arise with the new backend because we can sink instructions
(e.g. loads or extends) in more interesting ways than before, but I'm
not entirely sure.

Test coverage will be via the fuzz corpus once bytecodealliance#2453 lands.
crates/fuzzing/Cargo.toml Outdated Show resolved Hide resolved
crates/fuzzing/src/oracles.rs Outdated Show resolved Hide resolved
crates/fuzzing/src/oracles.rs Outdated Show resolved Hide resolved
crates/fuzzing/src/oracles.rs Outdated Show resolved Hide resolved
fuzz/Cargo.toml Outdated Show resolved Hide resolved
cfallin added a commit to cfallin/wasmtime that referenced this pull request Dec 2, 2020
A dynamic heap address computation may create up to two conditional
branches: the usual bounds-check, but also (in some cases) an
offset-addition overflow check.

The x64 backend had reversed the condition code for this check,
resulting in an always-trapping execution for a valid offset. I'm
somewhat surprised this has existed so long, but I suppose the
particular conditions (large offset, small offset guard, dynamic heap)
have been somewhat rare in our testing so far.

Found via fuzzing in bytecodealliance#2453.
cfallin added a commit to cfallin/wasmtime that referenced this pull request Dec 2, 2020
- Sort by generated-code offset to maintain invariant and avoid gimli
  panic.
- Fix srcloc interaction with branch peephole optimization in
  MachBuffer: if a srcloc range overlaps with a branch that is
  truncated, remove that srcloc range.

These issues were found while fuzzing the new backend (bytecodealliance#2453); I suspect
that they arise with the new backend because we can sink instructions
(e.g. loads or extends) in more interesting ways than before, but I'm
not entirely sure.

Test coverage will be via the fuzz corpus once bytecodealliance#2453 lands.
cfallin added a commit to cfallin/wasmtime that referenced this pull request Dec 2, 2020
A dynamic heap address computation may create up to two conditional
branches: the usual bounds-check, but also (in some cases) an
offset-addition overflow check.

The x64 backend had reversed the condition code for this check,
resulting in an always-trapping execution for a valid offset. I'm
somewhat surprised this has existed so long, but I suppose the
particular conditions (large offset, small offset guard, dynamic heap)
have been somewhat rare in our testing so far.

Found via fuzzing in bytecodealliance#2453.
cfallin added a commit to cfallin/wasmtime that referenced this pull request Dec 2, 2020
- Sort by generated-code offset to maintain invariant and avoid gimli
  panic.
- Fix srcloc interaction with branch peephole optimization in
  MachBuffer: if a srcloc range overlaps with a branch that is
  truncated, remove that srcloc range.

These issues were found while fuzzing the new backend (bytecodealliance#2453); I suspect
that they arise with the new backend because we can sink instructions
(e.g. loads or extends) in more interesting ways than before, but I'm
not entirely sure.

Test coverage will be via the fuzz corpus once bytecodealliance#2453 lands.
This PR adds a new fuzz target, `differential_wasmi`, that runs a
Cranelift-based Wasm backend alongside a simple third-party Wasm
interpeter crate (`wasmi`).  The fuzzing runs the first function in a
given module to completion on each side, and then diffs the return value
and linear memory contents.

This strategy should provide end-to-end coverage including both the Wasm
translation to CLIF (which has seen some subtle and scary bugs at
times), the lowering from CLIF to VCode, the register allocation, and
the final code emission.

This PR also adds a feature `experimental_x64` to the fuzzing crate (and
the chain of dependencies down to `cranelift-codegen`) so that we can
fuzz the new x86-64 backend as well as the current one.
@cfallin cfallin merged commit b93381e into bytecodealliance:main Dec 2, 2020
@cfallin cfallin deleted the differential-fuzz-interp branch January 6, 2021 18:03
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
fuzzing Issues related to our fuzzing infrastructure wasmtime:api Related to the API of the `wasmtime` crate itself
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants