From 49c2b1e60a87623796046176500bed6afa956d2f Mon Sep 17 00:00:00 2001 From: Alex Crichton Date: Wed, 23 Feb 2022 16:41:38 -0600 Subject: [PATCH] Fix image reuse with multi-memory images (#3846) This commit fixes a potential issue where the fast-path instantiate in `MemoryImageSlot` where when the previous image is compared against the new image it only performed file descriptor equality, but nowadays with loading images from `*.cwasm` files there might be multiple images in the same file so the offsets also need to be considered. I think this isn't really easy to hit today, it would require combining both module linking and multi-memory which gets into the realm of being pretty esoteric so I haven't added a test case here for this. --- crates/runtime/src/cow.rs | 17 ++++++++--------- 1 file changed, 8 insertions(+), 9 deletions(-) diff --git a/crates/runtime/src/cow.rs b/crates/runtime/src/cow.rs index b81a184783..7cd2987d1a 100644 --- a/crates/runtime/src/cow.rs +++ b/crates/runtime/src/cow.rs @@ -27,7 +27,7 @@ impl ModuleMemoryImages { } /// One backing image for one memory. -#[derive(Debug)] +#[derive(Debug, PartialEq)] pub struct MemoryImage { /// The file descriptor source of this image. /// @@ -75,6 +75,12 @@ impl FdSource { } } +impl PartialEq for FdSource { + fn eq(&self, other: &FdSource) -> bool { + self.as_file().as_raw_fd() == other.as_file().as_raw_fd() + } +} + impl MemoryImage { fn new( page_size: u32, @@ -348,14 +354,7 @@ impl MemoryImageSlot { // termination. The `clear_and_remain_ready()` path also // mprotects memory above the initial heap size back to // PROT_NONE, so we don't need to do that here. - if (self.image.is_none() - && maybe_image.is_none() - && self.initial_size == initial_size_bytes) - || (self.image.is_some() - && maybe_image.is_some() - && self.image.as_ref().unwrap().fd.as_file().as_raw_fd() - == maybe_image.as_ref().unwrap().fd.as_file().as_raw_fd()) - { + if self.image.as_ref() == maybe_image && self.initial_size == initial_size_bytes { self.dirty = true; return Ok(()); }