-
Notifications
You must be signed in to change notification settings - Fork 1.4k
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
Memcheck for Wasm guests in Wasmtime #6820
Memcheck for Wasm guests in Wasmtime #6820
Conversation
For some context for others: Sophia (@ssunkin-fastly) is our summer intern who has written a "Valgrind for Wasm" feature: we want to hook loads, stores, mallocs and frees inside a Wasm guest (presumably written in an unsafe language like C or C++) and catch memory safety violations (use-after-frees, double-frees, out-of-bounds indexing, etc.). The feature works at an MVP level with tests written in C/C++; it's not yet fully general (multi-memories, arbitrary annotations for custom allocators, etc) but we want to merge the MVP first and then file followup issues. @ssunkin-fastly: would you mind either rebasing or merging |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is looking really great! I have a whole bunch of minor comments but the overall shape of the code is good and we should be able to refine things fairly quickly, I think.
I know you're working on doc-comments but will note in particular that our CI checks will fail until there's a doc-comment on every public type, enum, function; it might feel a little tedious but it's good practice :-)
It'd be good to file some followup GitHub issues and refer to issue numbers where appropriate in comments as well. Off the top of my head:
- Support for multiple memories
- Support for instrumenting SIMD loads/stores
- Support for handling different memory layouts (assume whole initial memory size is valid, for example)
- Option to print valgrind errors and continue (as the "real Valgrind" does) rather than trap
and anything else on your to-do list you want to capture.
Happy to pair on any of the requests here if unclear!
crates/valgrind/src/lib.rs
Outdated
metadata: Vec<MemState>, | ||
mallocs: HashMap<usize, usize>, | ||
pub stack_pointer: usize, | ||
max_stack_size: usize, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
To reduce ambiguity I think this should be called stack_end
or something similar? ("Stack size" makes me think of the actual size, so a stack from 1MiB down to 1MiB - 4KiB is 4KiB large; but the "end" is 1MiB)
crates/valgrind/src/lib.rs
Outdated
@@ -0,0 +1,417 @@ | |||
use std::cmp::*; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Let's add a doc-comment at the top of this module like
//! add some docs here
//!
//! in markdown format, with multiple paragraphs as desired
//!
//! like this
documenting the assumptions about memory layout here.
crates/valgrind/src/lib.rs
Outdated
}); | ||
} else if new_sp < self.stack_pointer { | ||
for i in new_sp..self.stack_pointer + 1 { | ||
// +1 to account for sp == max_stack_size (?) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm somewhat surprised this is needed -- could we document the case where it is if so (example addresses or whatnot)?
src/commands/run.rs
Outdated
@@ -253,6 +253,10 @@ pub struct RunCommand { | |||
/// memory, for example. | |||
#[clap(long)] | |||
trap_on_grow_failure: bool, | |||
|
|||
/// Run valgrind |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We'll want a much longer doc-comment of course, probably with a pointer to documentation for more details on how to use!
(Trying again in case the qemu/tcg crash was spurious) |
This does indeed appear to be a qemu bug. Running the full testsuite natively with this patch works fine. When running under 7.2.0 qemu on Intel, I can reproduce the same TCG abort. It seems this a known problem fixed by this patch by @iii-i : Backporting that fix makes the abort go away. Not sure why this particular patch exposed this bug - but that may just be some random effect of qemu register allocation ... |
This should resolve a bug in qemu triggered by changes in bytecodealliance#6820 (see [here](bytecodealliance#6820 (comment))).
* CI: upgrade to qemu 8.0.4. This should resolve a bug in qemu triggered by changes in #6820 (see [here](#6820 (comment))). * ci: Update QEMU patch for 8.0.2 --------- Co-authored-by: Afonso Bordado <[email protected]>
* CI: upgrade to qemu 8.0.4. This should resolve a bug in qemu triggered by changes in bytecodealliance#6820 (see [here](bytecodealliance#6820 (comment))). * ci: Update QEMU patch for 8.0.2 --------- Co-authored-by: Afonso Bordado <[email protected]>
* attempt at inserting things where i think they might belong + questions * entry hook + questions * commented out all changes, doc comment errors * fix doc comment * libcalls build now!!!! * initial check_malloc_exit setup * WIP: load/store hooks * hooks added + building * added valgrind library * made wasm-valgrind accessible in wasmtime * check_malloc filled in... * move valgrind_state to an appropriate part of instance it works!!!!! * yay it's working! (?) i think?? * stack tracing in progress * errors + num bytes displayed * initial valgrind configuration * valgrind conditional some warnings fixed * conditional compilation + CLI flag finished * panic!() changed to bail!() * started adding doc comments * added memory grow hook + fixed access size handling * removed test.wasm * removed malloc_twice.wat * doc comments in spec.rs * pr feedback addressed * ran cargo fmt * addressing more feedback * Remove fuzz crate from wmemcheck. * Review feedback and test fix. * add wasmtime-wmemcheck crate to publish allowlist. * fix build without compiler features * reorder crates in publish list * Add trampolines for libcalls on s390x. * Make wasmtime-wmemcheck dep an exact version requirement. --------- Co-authored-by: iximeow <[email protected]> Co-authored-by: Chris Fallin <[email protected]> Co-authored-by: iximeow <[email protected]>
…time into feature/wasi-nn-preview-2 * 'feature/wasi-nn-preview-2' of github.com:geekbeast/wasmtime: Memcheck for Wasm guests in Wasmtime (bytecodealliance#6820) CI: upgrade to qemu 8.0.4. (bytecodealliance#6849) Sync wasi-cli with wit definitions in standards repo (bytecodealliance#6806) Rename `preview2::preview2` to `preview2::host` (bytecodealliance#6847) winch: Simplify the MacroAssembler and Assembler interfaces (bytecodealliance#6841) There are no files in `preview1` other than `mod.rs` (bytecodealliance#6845) Update stdio on Unix to fall back to worker threads (bytecodealliance#6833) Update RELEASES.md (bytecodealliance#6838) Minor documentation updates to docs/WASI-tutorial.md (bytecodealliance#6839) Add support for vector in DataValueExt::int() (bytecodealliance#6844)
* CI: upgrade to qemu 8.0.4. This should resolve a bug in qemu triggered by changes in bytecodealliance#6820 (see [here](bytecodealliance#6820 (comment))). * ci: Update QEMU patch for 8.0.2 --------- Co-authored-by: Afonso Bordado <[email protected]>
* CI: upgrade to qemu 8.0.4. This should resolve a bug in qemu triggered by changes in bytecodealliance#6820 (see [here](bytecodealliance#6820 (comment))). * ci: Update QEMU patch for 8.0.2 --------- Co-authored-by: Afonso Bordado <[email protected]>
* Fix test expectations [automatically-tag-and-release-this-commit] * CI: upgrade to qemu 8.0.4. (#6849) * CI: upgrade to qemu 8.0.4. This should resolve a bug in qemu triggered by changes in #6820 (see [here](#6820 (comment))). * ci: Update QEMU patch for 8.0.2 --------- Co-authored-by: Afonso Bordado <[email protected]> --------- Co-authored-by: Chris Fallin <[email protected]> Co-authored-by: Afonso Bordado <[email protected]>
* Fix test expectations [automatically-tag-and-release-this-commit] * CI: upgrade to qemu 8.0.4. (#6849) * CI: upgrade to qemu 8.0.4. This should resolve a bug in qemu triggered by changes in #6820 (see [here](#6820 (comment))). * ci: Update QEMU patch for 8.0.2 --------- Co-authored-by: Afonso Bordado <[email protected]> --------- Co-authored-by: Chris Fallin <[email protected]> Co-authored-by: Afonso Bordado <[email protected]>
* Fix test expectations [automatically-tag-and-release-this-commit] * CI: upgrade to qemu 8.0.4. (bytecodealliance#6849) * CI: upgrade to qemu 8.0.4. This should resolve a bug in qemu triggered by changes in bytecodealliance#6820 (see [here](bytecodealliance#6820 (comment))). * ci: Update QEMU patch for 8.0.2 --------- Co-authored-by: Afonso Bordado <[email protected]> --------- Co-authored-by: Chris Fallin <[email protected]> Co-authored-by: Afonso Bordado <[email protected]>
This PR introduces
wmemcheck
, a memory checker for a Wasm guest running inside Wasmtime.wmemcheck
operates by recognizing calls to malloc and free inside the Wasm module, and tracking which bytes are valid. It then instruments loads and stores and flags errors when accesses are invalid. This is inspired by thememcheck
tool in Valgrind, hence the name.The functionality is off by default and is enabled with
wasmtime run --wmemcheck
.Co-authored-by: Chris Fallin [email protected]
Co-authored-by: iximeow [email protected]