bytecodealliance / bytecodealliance/wasmtime

Improve libFuzzer feedback of Cranelift lowerings actually executed at runtime

Open
#9,255 2 comments 0 reactions 0 assignees View on GitHub
fuzzing
Dominant language
Rust
Stars
18.6k
Forks
1.8k
Avg merge
1d 18h
Merged PRs (30d)
126

Description

One of the things we've struggled with historically in fuzzing is generating interesting enough WebAssembly modules which execute interesting corner cases without trapping almost immediately. For example many wasm-smith modules might immediately have an infinite loop, immediately infinitely recurse, or immediately trap with an out of bounds load. For all of these conditions we have various checks and balances in place to ensure that we get hopefully some better coverage, but I was just thinking of another possible way we could improve it.

What I'm imagining is that we can leverage libFuzzer's coverage-based feedback with a scheme such as:

* Fix a constant N at a big number, maybe 10_000
* Allocate N bytes extra in all VMContexts when this feature is enabled, and initialize all bytes to zero
* Assign a unique number to all Cranelift lowering rules
* When a lowering I rule is used, then after the lowering rule is matched increment the byte at `I % N` in the VMContext
* When fuzzing, enable this option (perhaps only sometimes?). After WebAssembly execution is performed take a look at the map on each `VMContext` (maybe this is a per-store map then instead of per-`VMContext`?)
* Define N empty functions at compile time with gobbledegook to make sure they don't get optimized away
* For each byte in the map that has been incremented call function N.

The hope is that this scheme enables libFuzzer to see what actually happened at runtime. It can know that not only was the lowering rule executed in Cranelift but addtionally the generated code was executed at runtime. WIth N being sufficiently high enough we could get pretty good coverage of "actually executed this lowering rule in a fuzz test case".

I'll note that this is similar to #1151 in spirit and that there'd still be a lot of details to work out here. For example how exactly to model this in Cranelift would be tricky as right now there's not an easy notion of "this lowering rule I was used" nor would it necessarily be easy to inject code to modify bytes during lowering. In any case though I figured I could note down the issue for possible future exploration.

Contributor guide

Open the contributing guide

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.