Skip to content

Commit

Permalink
Fixed a memory corruption issue with JS memory operations that were r…
Browse files Browse the repository at this point in the history
…eusing invalid views
  • Loading branch information
john-sharratt committed Jul 30, 2022
1 parent 00ce911 commit 3374863
Show file tree
Hide file tree
Showing 71 changed files with 1,049 additions and 962 deletions.
1 change: 1 addition & 0 deletions Cargo.lock

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

4 changes: 2 additions & 2 deletions examples/engine_cross_compilation.rs
Original file line number Diff line number Diff line change
Expand Up @@ -69,10 +69,10 @@ fn main() -> Result<(), Box<dyn std::error::Error>> {
// That's where we specify the target for the compiler.
//
// Use the Universal engine.
let mut engine = EngineBuilder::new(compiler_config).set_target(Some(target));
let engine = EngineBuilder::new(compiler_config).set_target(Some(target));

// Create a store, that holds the engine.
let mut store = Store::new(engine);
let store = Store::new(engine);

println!("Compiling module...");
// Let's compile the Wasm module.
Expand Down
4 changes: 2 additions & 2 deletions examples/engine_headless.rs
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,7 @@ fn main() -> Result<(), Box<dyn std::error::Error>> {
let compiler = Cranelift::default();

// Create a store, that holds the engine.
let mut store = Store::new(compiler);
let store = Store::new(compiler);

println!("Compiling module...");
// Let's compile the Wasm module.
Expand All @@ -96,7 +96,7 @@ fn main() -> Result<(), Box<dyn std::error::Error>> {
// We create a headless Universal engine.
let engine = EngineBuilder::headless();
let mut store = Store::new(engine);
let mut env = FunctionEnv::new(&mut store, ());
let _env = FunctionEnv::new(&mut store, ());

println!("Deserializing module...");
// Here we go.
Expand Down
2 changes: 1 addition & 1 deletion examples/errors.rs
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ fn main() -> Result<(), Box<dyn std::error::Error>> {
// the default provided by Wasmer.
// You can use `Store::default()` for that.
let mut store = Store::new(Cranelift::default());
let mut env = FunctionEnv::new(&mut store, ());
let _env = FunctionEnv::new(&mut store, ());

println!("Compiling module...");
// Let's compile the Wasm module.
Expand Down
2 changes: 1 addition & 1 deletion examples/exports_function.rs
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ fn main() -> Result<(), Box<dyn std::error::Error>> {
// the default provided by Wasmer.
// You can use `Store::default()` for that.
let mut store = Store::new(Cranelift::default());
let mut env = FunctionEnv::new(&mut store, ());
let _env = FunctionEnv::new(&mut store, ());

println!("Compiling module...");
// Let's compile the Wasm module.
Expand Down
2 changes: 1 addition & 1 deletion examples/exports_global.rs
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ fn main() -> Result<(), Box<dyn std::error::Error>> {
// the default provided by Wasmer.
// You can use `Store::default()` for that.
let mut store = Store::new(Cranelift::default());
let mut env = FunctionEnv::new(&mut store, ());
let _env = FunctionEnv::new(&mut store, ());

println!("Compiling module...");
// Let's compile the Wasm module.
Expand Down
16 changes: 9 additions & 7 deletions examples/exports_memory.rs
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ fn main() -> Result<(), Box<dyn std::error::Error>> {
// the default provided by Wasmer.
// You can use `Store::default()` for that.
let mut store = Store::new(Cranelift::default());
let mut env = FunctionEnv::new(&mut store, ());
let _env = FunctionEnv::new(&mut store, ());

println!("Compiling module...");
// Let's compile the Wasm module.
Expand All @@ -57,14 +57,15 @@ fn main() -> Result<(), Box<dyn std::error::Error>> {
//
// The Wasm module exports a memory under "mem". Let's get it.
let memory = instance.exports.get_memory("mem")?;

// Now that we have the exported memory, let's get some
// information about it.
//
// The first thing we might be intersted in is the size of the memory.
// Let's get it!
println!("Memory size (pages) {:?}", memory.size(&mut store));
println!("Memory size (bytes) {:?}", memory.data_size(&mut store));
let memory_view = memory.view(&store);
println!("Memory size (pages) {:?}", memory_view.size());
println!("Memory size (bytes) {:?}", memory_view.data_size());

// Oh! Wait, before reading the contents, we need to know
// where to find what we are looking for.
Expand All @@ -79,8 +80,9 @@ fn main() -> Result<(), Box<dyn std::error::Error>> {
//
// We will get bytes out of the memory so we need to
// decode them into a string.
let memory_view = memory.view(&store);
let str = ptr
.read_utf8_string(&mut store, memory, length as u32)
.read_utf8_string(&memory_view, length as u32)
.unwrap();
println!("Memory contents: {:?}", str);

Expand All @@ -90,7 +92,7 @@ fn main() -> Result<(), Box<dyn std::error::Error>> {
// To do that, we'll make a slice from our pointer and change the content
// of each element.
let new_str = b"Hello, Wasmer!";
let values = ptr.slice(&mut store, memory, new_str.len() as u32).unwrap();
let values = ptr.slice(&memory_view, new_str.len() as u32).unwrap();
for i in 0..new_str.len() {
values.index(i as u64).write(new_str[i]).unwrap();
}
Expand All @@ -103,7 +105,7 @@ fn main() -> Result<(), Box<dyn std::error::Error>> {
println!("New string length: {:?}", new_str.len());

let str = ptr
.read_utf8_string(&mut store, memory, new_str.len() as u32)
.read_utf8_string(&memory_view, new_str.len() as u32)
.unwrap();
println!("New memory contents: {:?}", str);

Expand Down
2 changes: 1 addition & 1 deletion examples/features.rs
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ fn main() -> anyhow::Result<()> {

// Now, let's define the store, and compile the module.
let mut store = Store::new(engine);
let mut env = FunctionEnv::new(&mut store, ());
let _env = FunctionEnv::new(&mut store, ());
let module = Module::new(&store, wasm_bytes)?;

// Finally, let's instantiate the module, and execute something
Expand Down
2 changes: 1 addition & 1 deletion examples/hello_world.rs
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@ fn main() -> anyhow::Result<()> {

// Next we'll set up our `Module` so that we can execute it. First, create
// a `FunctionEnv` in which to instantiate our `Module`.
let mut context = FunctionEnv::new(&mut store, ());
let context = FunctionEnv::new(&mut store, ());

// We define a function to act as our "env" "say_hello" function imported in the
// Wasm program above.
Expand Down
2 changes: 1 addition & 1 deletion examples/imports_exports.rs
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ fn main() -> Result<(), Box<dyn std::error::Error>> {
// the default provided by Wasmer.
// You can use `Store::default()` for that.
let mut store = Store::new(Cranelift::default());
let mut env = FunctionEnv::new(&mut store, ());
let env = FunctionEnv::new(&mut store, ());

println!("Compiling module...");
// Let's compile the Wasm module.
Expand Down
4 changes: 2 additions & 2 deletions examples/imports_function.rs
Original file line number Diff line number Diff line change
Expand Up @@ -45,9 +45,9 @@ fn main() -> Result<(), Box<dyn std::error::Error>> {
// the default provided by Wasmer.
// You can use `Store::default()` for that.
let mut store = Store::new(Cranelift::default());
let mut env1 = FunctionEnv::new(&mut store, ());
let env1 = FunctionEnv::new(&mut store, ());
struct MyEnv;
let mut env2 = FunctionEnv::new(&mut store, MyEnv {});
let env2 = FunctionEnv::new(&mut store, MyEnv {});

println!("Compiling module...");
// Let's compile the Wasm module.
Expand Down
2 changes: 1 addition & 1 deletion examples/imports_function_env.rs
Original file line number Diff line number Diff line change
Expand Up @@ -87,7 +87,7 @@ fn main() -> Result<(), Box<dyn std::error::Error>> {
*counter_ref
}

let mut env = FunctionEnv::new(
let env = FunctionEnv::new(
&mut store,
Env {
counter: shared_counter.clone(),
Expand Down
2 changes: 1 addition & 1 deletion examples/imports_global.rs
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ fn main() -> Result<(), Box<dyn std::error::Error>> {
// the default provided by Wasmer.
// You can use `Store::default()` for that.
let mut store = Store::new(Cranelift::default());
let mut env = FunctionEnv::new(&mut store, ());
let _env = FunctionEnv::new(&mut store, ());

println!("Compiling module...");
// Let's compile the Wasm module.
Expand Down
2 changes: 1 addition & 1 deletion examples/instance.rs
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ fn main() -> Result<(), Box<dyn std::error::Error>> {
// the default provided by Wasmer.
// You can use `Store::default()` for that.
let mut store = Store::new(Cranelift::default());
let mut env = FunctionEnv::new(&mut store, ());
let _env = FunctionEnv::new(&mut store, ());

println!("Compiling module...");
// Let's compile the Wasm module.
Expand Down
26 changes: 16 additions & 10 deletions examples/memory.rs
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,7 @@ fn main() -> anyhow::Result<()> {
// the default provided by Wasmer.
// You can use `Store::default()` for that.
let mut store = Store::new(Cranelift::default());
let mut env = FunctionEnv::new(&mut store, ());
let _env = FunctionEnv::new(&mut store, ());

println!("Compiling module...");
// Let's compile the Wasm module.
Expand All @@ -83,7 +83,7 @@ fn main() -> anyhow::Result<()> {
let set_at: TypedFunction<(i32, i32), ()> =
instance.exports.get_typed_function(&mut store, "set_at")?;
let memory = instance.exports.get_memory("memory")?;

// We now have an instance ready to be used.
//
// We will start by querying the most intersting information
Expand All @@ -95,27 +95,33 @@ fn main() -> anyhow::Result<()> {
// The size in bytes can be found either by querying its pages or by
// querying the memory directly.
println!("Querying memory size...");
assert_eq!(memory.size(&mut store), Pages::from(1));
assert_eq!(memory.size(&mut store).bytes(), Bytes::from(65536 as usize));
assert_eq!(memory.data_size(&mut store), 65536);

let memory_view = memory.view(&store);
assert_eq!(memory_view.size(), Pages::from(1));
assert_eq!(memory_view.size().bytes(), Bytes::from(65536 as usize));
assert_eq!(memory_view.data_size(), 65536);

// Sometimes, the guest module may also export a function to let you
// query the memory. Here we have a `mem_size` function, let's try it:
let result = mem_size.call(&mut store)?;

let memory_view = memory.view(&store);
println!("Memory size: {:?}", result);
assert_eq!(Pages::from(result as u32), memory.size(&mut store));
assert_eq!(Pages::from(result as u32), memory_view.size());

// Now that we know the size of our memory, it's time to see how wa
// can change this.
//
// A memory can be grown to allow storing more things into it. Let's
// see how we can do that:
println!("Growing memory...");

// Here we are requesting two more pages for our memory.
memory.grow(&mut store, 2)?;
assert_eq!(memory.size(&mut store), Pages::from(3));
assert_eq!(memory.data_size(&mut store), 65536 * 3);


let memory_view = memory.view(&store);
assert_eq!(memory_view.size(), Pages::from(3));
assert_eq!(memory_view.data_size(), 65536 * 3);

// Now that we know how to query and adjust the size of the memory,
// let's see how wa can write to it or read from it.
//
Expand Down
2 changes: 1 addition & 1 deletion examples/metering.rs
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,7 @@ fn main() -> anyhow::Result<()> {
// We use our previously create compiler configuration
// with the Universal engine.
let mut store = Store::new(EngineBuilder::new(compiler_config));
let mut env = FunctionEnv::new(&mut store, ());
let _env = FunctionEnv::new(&mut store, ());

println!("Compiling module...");
// Let's compile the Wasm module.
Expand Down
2 changes: 1 addition & 1 deletion examples/platform_ios_headless.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
//! ```
//!
//! Ready?
#![allow(unused)]
use std::path::Path;
use std::str::FromStr;
use wasmer::{wat2wasm, Module, RuntimeError, Store};
Expand Down
2 changes: 1 addition & 1 deletion examples/table.rs
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ fn main() -> anyhow::Result<()> {

// We set up our store with an engine and a compiler.
let mut store = Store::new(Cranelift::default());
let mut env = FunctionEnv::new(&mut store, ());
let env = FunctionEnv::new(&mut store, ());
// Then compile our Wasm.
let module = Module::new(&store, wasm_bytes)?;
let import_object = imports! {};
Expand Down
2 changes: 1 addition & 1 deletion examples/tunables_limit_memory.rs
Original file line number Diff line number Diff line change
Expand Up @@ -143,7 +143,7 @@ fn main() -> Result<(), Box<dyn std::error::Error>> {

// Create a store, that holds the engine and our custom tunables
let mut store = Store::new_with_tunables(compiler, tunables);
let mut env = FunctionEnv::new(&mut store, ());
let _env = FunctionEnv::new(&mut store, ());

println!("Compiling module...");
let module = Module::new(&store, wasm_bytes)?;
Expand Down
4 changes: 2 additions & 2 deletions examples/wasi.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@
//!
//! Ready?
use wasmer::{FunctionEnv, Instance, Module, Store};
use wasmer::{Instance, Module, Store};
use wasmer_compiler_cranelift::Cranelift;
use wasmer_wasi::WasiState;

Expand All @@ -39,7 +39,7 @@ fn main() -> Result<(), Box<dyn std::error::Error>> {

println!("Creating `WasiEnv`...");
// First, we create the `WasiEnv`
let mut wasi_env = WasiState::new("hello")
let wasi_env = WasiState::new("hello")
// .args(&["world"])
// .env("KEY", "Value")
.finalize(&mut store)?;
Expand Down
4 changes: 2 additions & 2 deletions examples/wasi_pipes.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
//! Ready?
use std::io::{Read, Write};
use wasmer::{FunctionEnv, Instance, Module, Store};
use wasmer::{Instance, Module, Store};
use wasmer_compiler_cranelift::Cranelift;
use wasmer_wasi::{Pipe, WasiState};

Expand All @@ -38,7 +38,7 @@ fn main() -> Result<(), Box<dyn std::error::Error>> {
// First, we create the `WasiEnv` with the stdio pipes
let mut input = Pipe::new();
let mut output = Pipe::new();
let mut wasi_env = WasiState::new("hello")
let wasi_env = WasiState::new("hello")
.stdin(Box::new(input.clone()))
.stdout(Box::new(output.clone()))
.finalize(&mut store)?;
Expand Down
2 changes: 1 addition & 1 deletion fuzz/fuzz_targets/universal_cranelift.rs
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ fuzz_target!(|module: WasmSmithModule| {
compiler.enable_verifier();
let mut store = Store::new(compiler);
let module = Module::new(&store, &wasm_bytes).unwrap();
match Instance::new(&module, &imports! {}) {
match Instance::new(&mut store, &module, &imports! {}) {
Ok(_) => {}
Err(e) => {
let error_message = format!("{}", e);
Expand Down
1 change: 1 addition & 0 deletions lib/api/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ indexmap = { version = "1.6", features = ["serde-1"] }
cfg-if = "1.0"
thiserror = "1.0"
more-asserts = "0.2"
tracing = "0.1"
# - Optional shared dependencies.
wat = { version = "1.0", optional = true }

Expand Down
8 changes: 4 additions & 4 deletions lib/api/src/js/externals/function.rs
Original file line number Diff line number Diff line change
Expand Up @@ -115,7 +115,7 @@ impl Function {
let wrapped_func: JsValue = match function_type.results().len() {
0 => Closure::wrap(Box::new(move |args: &Array| {
let mut store: StoreMut = unsafe { StoreMut::from_raw(raw_store as _) };
let mut env: FunctionEnvMut<T> = raw_env.clone().into_mut(&mut store);
let env: FunctionEnvMut<T> = raw_env.clone().into_mut(&mut store);
let wasm_arguments = function_type
.params()
.iter()
Expand All @@ -129,7 +129,7 @@ impl Function {
.into_js_value(),
1 => Closure::wrap(Box::new(move |args: &Array| {
let mut store: StoreMut = unsafe { StoreMut::from_raw(raw_store as _) };
let mut env: FunctionEnvMut<T> = raw_env.clone().into_mut(&mut store);
let env: FunctionEnvMut<T> = raw_env.clone().into_mut(&mut store);
let wasm_arguments = function_type
.params()
.iter()
Expand All @@ -143,7 +143,7 @@ impl Function {
.into_js_value(),
_n => Closure::wrap(Box::new(move |args: &Array| {
let mut store: StoreMut = unsafe { StoreMut::from_raw(raw_store as _) };
let mut env: FunctionEnvMut<T> = raw_env.clone().into_mut(&mut store);
let env: FunctionEnvMut<T> = raw_env.clone().into_mut(&mut store);
let wasm_arguments = function_type
.params()
.iter()
Expand Down Expand Up @@ -509,7 +509,7 @@ mod inner {
use super::RuntimeError;
use super::VMFunctionBody;
use crate::js::function_env::{FunctionEnvMut, VMFunctionEnvironment};
use crate::js::store::{AsStoreMut, InternalStoreHandle, StoreHandle, StoreInner, StoreMut};
use crate::js::store::{AsStoreMut, InternalStoreHandle, StoreHandle, StoreMut};
use crate::js::FunctionEnv;
use crate::js::NativeWasmTypeInto;
use std::array::TryFromSliceError;
Expand Down
Loading

0 comments on commit 3374863

Please sign in to comment.