abrown opened PR #5229 from shmem-in-wiggle-copy-and-unsafe to main:
When multiple threads can concurrently modify a WebAssembly shared memory, the underlying data for a Wiggle
GuestSliceandGuestSliceMutcould change due to access from other threads. This breaks Rust guarantees when&[T]and&mut [T]slices are handed out. This change modifiesGuestPtrto makeas_sliceandas_slice_mutreturn anOptionwhich isNonewhen the underlying WebAssembly memory is shared.But WASI implementations still need access to the underlying WebAssembly memory, both to read to it and write from it. This change adds new APIs:
GuestPtr::to_veccopies the bytes from WebAssembly memory (from which we can safely take a&[T])GuestPtr::as_unsafe_slice_mutreturns a wrapperstructfrom which we canunsafe-ly return a mutable slice (users must accept the unsafety of concurrently modifying a&mut [T])This approach allows us to maintain Wiggle's borrow-checking infrastructure, which enforces the guarantee that Wiggle will not modify overlapping regions, e.g. This is important because the underlying system calls may expect this. Though other threads may modify the same underlying region, this is impossible to prevent; at least Wiggle will not be able to do so.
Finally, the changes to Wiggle's API are propagated to all WASI implementations in Wasmtime. For now, code locations that attempt to get a guest slice will panic if the underlying memory is shared. Note that Wiggle is not enabled for shared memory (that will come later in something like #5054), but when it is, these panics will be clear indicators of locations that must be re-implemented in a thread-safe way.
<!--
Please ensure that the following steps are all taken care of before submitting
the PR.
[ ] This has been discussed in issue #..., or if not, please tell us why
here.[ ] A short description of what this does, why it is needed; if the
description becomes long, the matter should probably be discussed in an issue
first.[ ] This PR contains test cases, if meaningful.
- [ ] A reviewer from the core maintainer team has been assigned for this PR.
If you don't know who could review this, please indicate so. The list of
suggested reviewers on the right can help you.Please ensure all communication adheres to the code of conduct.
-->
abrown edited PR #5229 from shmem-in-wiggle-copy-and-unsafe to main:
When multiple threads can concurrently modify a WebAssembly shared memory, the underlying data for a Wiggle
GuestSliceandGuestSliceMutcould change due to access from other threads. This breaks Rust guarantees when&[T]and&mut [T]slices are handed out. This change modifiesGuestPtrto makeas_sliceandas_slice_mutreturn anOptionwhich isNonewhen the underlying WebAssembly memory is shared.But WASI implementations still need access to the underlying WebAssembly memory, both to read to it and write from it. This change adds new APIs:
GuestPtr::to_veccopies the bytes from WebAssembly memory (from which we can safely take a&[T])GuestPtr::as_unsafe_slice_mutreturns a wrapperstructfrom which we canunsafe-ly return a mutable slice (users must accept the unsafety of concurrently modifying a&mut [T])This approach allows us to maintain Wiggle's borrow-checking infrastructure, which enforces the guarantee that Wiggle will not modify overlapping regions, e.g. This is important because the underlying system calls may expect this. Other threads may modify the same underlying region and this is impossible to prevent; at least Wiggle will not be able to do so.
Finally, the changes to Wiggle's API are propagated to all WASI implementations in Wasmtime. For now, code locations that attempt to get a guest slice will panic if the underlying memory is shared. Note that Wiggle is not enabled for shared memory (that will come later in something like #5054), but when it is, these panics will be clear indicators of locations that must be re-implemented in a thread-safe way.
<!--
Please ensure that the following steps are all taken care of before submitting
the PR.
[ ] This has been discussed in issue #..., or if not, please tell us why
here.[ ] A short description of what this does, why it is needed; if the
description becomes long, the matter should probably be discussed in an issue
first.[ ] This PR contains test cases, if meaningful.
- [ ] A reviewer from the core maintainer team has been assigned for this PR.
If you don't know who could review this, please indicate so. The list of
suggested reviewers on the right can help you.Please ensure all communication adheres to the code of conduct.
-->
abrown updated PR #5229 from shmem-in-wiggle-copy-and-unsafe to main.
alexcrichton submitted PR review.
alexcrichton submitted PR review.
alexcrichton created PR review comment:
Could the
expectmessages here be replaced with something along the lines of aTODO: ..to clarify that there's nothing a user running into this can do to fix things, it requires source changes here.
alexcrichton created PR review comment:
double
as *mut Tcast?
alexcrichton created PR review comment:
Could this have a comment, or a reference, for why shared memory is rejected here?
alexcrichton created PR review comment:
Could you update the documentation of this function to indicate what the
Optionreturn means?
alexcrichton created PR review comment:
We'll need to be careful here because the mere presence of
&mut [T], however ephemeral it is, will be UB for Rust that we need to avoid. Basically the raw-pointer-ness needs to get plumbed all the way down to thestd::ptr::copy.Also, can you be sure to tag this
std::ptr::copyin the threads issue as "please audit at some point" along the lines of the other copies already inruntime/src/instances.rs
alexcrichton created PR review comment:
Or sort of more generally I think it's worth writing down somewhere the general idea behind shared memory and how it works in wiggle, and then link to that as part of various comments.
alexcrichton created PR review comment:
Could this perhaps be refactored with the result or such to be usable as an internal implementation detail of the two methods above? Deduplicating the bounds checks would be pretty convenient and the "Unsafe" version could then have a methods
{shared,mut}_borrowto give the safe versions, returningNonefor shared memories.basically
as_slice()could be a small wrapper aroundOk(self.as_unsafe_slice().shared_borrow())or something like that.
alexcrichton created PR review comment:
Similar requests as above for doc updates and comments on the test for shared memory here
alexcrichton created PR review comment:
Also, given the sheer quantity of these, I think it might be good to have some sort of greppable string in the message here so an entry can be added to the threads tracking issue of how to find places to resolve.
abrown updated PR #5229 from shmem-in-wiggle-copy-and-unsafe to main.
abrown updated PR #5229 from shmem-in-wiggle-copy-and-unsafe to main.
alexcrichton submitted PR review.
alexcrichton created PR review comment:
I don't think that this is doing what you might expect, I think this'll need to be written with
std::slice::from_raw_parts. That being said I think it's best to dropas_sliceandas_slice_muthere for now since nothing needs it. I think these would be better modeled as aDeref<Target = [UnsafeCell<T>]>in the future if it's necessary.
alexcrichton created PR review comment:
Could this method be implemented with
as_unsafe_slice_mutto deduplicate the bits internally?
alexcrichton created PR review comment:
For this this will still need to be implemented with an actual call to
std::ptr::copy. I know for a fact that anything other than that is inherently UB, the only question to me is whetherstd::ptr::copyis UB-or-not in this situation.
alexcrichton submitted PR review.
abrown updated PR #5229 from shmem-in-wiggle-copy-and-unsafe to main.
abrown updated PR #5229 from shmem-in-wiggle-copy-and-unsafe to main.
abrown has marked PR #5229 as ready for review.
alexcrichton submitted PR review.
alexcrichton submitted PR review.
alexcrichton created PR review comment:
I believe this will need to do a
guest_slice.mut_borrow()?;before doing this copy to return an error if this is already borrowed for unshared memories.
abrown submitted PR review.
abrown created PR review comment:
I have
UnsafeGuestSlice::mut_borrow(self)which then makes it difficult to either use the mutable borrow or use the unsafe slice forstd::ptr::copy. Should it take&mut selfinstead?
alexcrichton submitted PR review.
alexcrichton created PR review comment:
While no longer compatible with
?how about:enum BorrowResult<T,S> { Ok(T), Shared(S), Err(GuestError), }as the return value? So that way given a
Sharederror you can still get at the internal pointer.While you could change
mut_burrowto&mut selfit would require still having theselfversion to get the lifetimes onas_slice_mutto work.
abrown updated PR #5229 from shmem-in-wiggle-copy-and-unsafe to main.
alexcrichton submitted PR review.
alexcrichton has enabled auto merge for PR #5229.
abrown updated PR #5229 from shmem-in-wiggle-copy-and-unsafe to main.
alexcrichton merged PR #5229.
Last updated: Dec 06 2025 at 06:05 UTC