Merge pull request from GHSA-wh6w-3828-g9qf

* Unconditionally use `MemoryImageSlot`

This commit removes the internal branching within the pooling instance
allocator to sometimes use a `MemoryImageSlot` and sometimes now.
Instead this is now unconditionally used in all situations on all
platforms. This fixes an issue where the state of a slot could get
corrupted if modules being instantiated switched from having images to
not having an image or vice versa.

The bulk of this commit is the removal of the `memory-init-cow`
compile-time feature in addition to adding Windows support to the
`cow.rs` file.

* Fix compile on Unix

* Add a stricter assertion for static memory bounds

Double-check that when a memory is allocated the configuration required
is satisfied by the pooling allocator.
This commit is contained in:
Alex Crichton
2022-11-10 11:34:38 -06:00
committed by GitHub
parent 47fa1ad6a8
commit 3535acbf3b
16 changed files with 245 additions and 331 deletions

View File

@@ -579,6 +579,63 @@ fn drop_externref_global_during_module_init() -> Result<()> {
Ok(())
}
#[test]
fn switch_image_and_non_image() -> Result<()> {
let mut pool = PoolingAllocationConfig::default();
pool.instance_count(1);
let mut c = Config::new();
c.allocation_strategy(InstanceAllocationStrategy::Pooling(pool));
let engine = Engine::new(&c)?;
let module1 = Module::new(
&engine,
r#"
(module
(memory 1)
(func (export "load") (param i32) (result i32)
local.get 0
i32.load
)
)
"#,
)?;
let module2 = Module::new(
&engine,
r#"
(module
(memory (export "memory") 1)
(data (i32.const 0) "1234")
)
"#,
)?;
let assert_zero = || -> Result<()> {
let mut store = Store::new(&engine, ());
let instance = Instance::new(&mut store, &module1, &[])?;
let func = instance.get_typed_func::<i32, i32, _>(&mut store, "load")?;
assert_eq!(func.call(&mut store, 0)?, 0);
Ok(())
};
// Initialize with a heap image and make sure the next instance, without an
// image, is zeroed
Instance::new(&mut Store::new(&engine, ()), &module2, &[])?;
assert_zero()?;
// ... transition back to heap image and do this again
Instance::new(&mut Store::new(&engine, ()), &module2, &[])?;
assert_zero()?;
// And go back to an image and make sure it's read/write on the host.
let mut store = Store::new(&engine, ());
let instance = Instance::new(&mut store, &module2, &[])?;
let memory = instance.get_memory(&mut store, "memory").unwrap();
let mem = memory.data_mut(&mut store);
assert!(mem.starts_with(b"1234"));
mem[..6].copy_from_slice(b"567890");
Ok(())
}
#[test]
#[cfg(target_pointer_width = "64")]
fn instance_too_large() -> Result<()> {