Skip to content
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

MemoryImageSlot doesn't handle the case where RuntimeLinearMemory::byte_size is not host page-aligned #9660

Open
sunshowers opened this issue Nov 22, 2024 · 1 comment

Comments

@sunshowers
Copy link
Contributor

Discovered this while working on #9652.

Looking at LocalMemory::new:

let mut slot = MemoryImageSlot::create(
alloc.base_ptr().cast(),
alloc.byte_size(),
alloc.byte_capacity(),

It passes in alloc.byte_size() as the accessible parameter to MemoryImageSlot::create:

pub(crate) fn create(base_addr: *mut c_void, accessible: usize, static_size: usize) -> Self {
MemoryImageSlot {
base: NonNull::new(base_addr.cast()).unwrap().into(),
static_size,
accessible,
image: None,
dirty: false,
clear_on_drop: true,
}

self.accessible is not rounded up to the host page size and is instead stored directly. But other places assume that self.accessible is page-aligned, for example:

self.set_protection(self.accessible..initial_size_bytes_page_aligned, true)?;

This ends up resolving to mprotect:

pub unsafe fn expose_existing_mapping(ptr: *mut u8, len: usize) -> io::Result<()> {
mprotect(ptr.cast(), len, MprotectFlags::READ | MprotectFlags::WRITE)?;
Ok(())

mprotect requires that its address is page-aligned, and will produce an EINVAL if it isn't.

I think there are likely also places where it panics or possibly even causes UB.

@sunshowers sunshowers changed the title MemoryImageSlot doesn't handle the case where RuntimeLinearMemory::byte_size is not page-aligned MemoryImageSlot doesn't handle the case where RuntimeLinearMemory::byte_size is not host page-aligned Nov 22, 2024
@sunshowers
Copy link
Contributor Author

In Zulip we decided to:

  • for now, skip attempting to do CoW if byte_size is smaller than the host page size
  • in the future, extend MemoryImageSlot to track both the accessible size and a rounded-up form of it.

sunshowers added a commit to sunshowers/wasmtime that referenced this issue Nov 22, 2024
sunshowers added a commit to sunshowers/wasmtime that referenced this issue Nov 22, 2024
github-merge-queue bot pushed a commit that referenced this issue Nov 22, 2024
* move most of runtime/vm/cow.rs over to aligned byte counts

As part of attempting to move some of these operations over to Mmap instances,
it is nice to have type-level checking for aligned sizes. In upcoming PRs, APIs
like `map_at` will be switched to using `Mmap` instances with aligned counts.

There are a couple of spots where I have questions -- will flag them in review
comments.

* address review comments, incl workaround for #9660
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant