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

runtime: simplify MemoryLike trait #8155

Merged
merged 17 commits into from
Dec 8, 2022
Merged

runtime: simplify MemoryLike trait #8155

merged 17 commits into from
Dec 8, 2022

Conversation

mina86
Copy link
Contributor

@mina86 mina86 commented Dec 3, 2022

read_memory and write_memory have to perform the same checks as
fits_memory already does. So rather than panicking, change the
methods to return an error. This makes the interface panic-free
and in some situations allows fits_memory call to be skipped.

However, separate fits_memory check may still be necessary so
keep the method but document in detail why it’s needed and, to
keep interfaces consistent, change it to return a Result.

Finally, read_memory_u8 is never used so get rid of it.

While at it, add tests for WasmerMemory. Essentially copies
of tests from Wasmer2Memory.

Firstly, read_memory_u8 is never used so get rid of it.

Secondly, fits_memory is always used in tandem with read_memory or
write_memory.  Rather than having the check as separate method,
include the bounds check in the latter two methods.  This changes them
from panicking to returning an error when trying to access memory out
of bounds.

While at it, add tests for WasmerMemory.  Esentially copies of tests
from Wasmer2Memory.
@mina86 mina86 requested a review from a team as a code owner December 3, 2022 16:16
@mina86 mina86 requested a review from mzhangmzz December 3, 2022 16:16
Copy link
Collaborator

@nagisa nagisa left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Really nice!

runtime/near-vm-runner/src/wasmtime_runner.rs Outdated Show resolved Hide resolved
runtime/near-vm-runner/src/memory.rs Outdated Show resolved Hide resolved
Co-authored-by: Simonas Kazlauskas <github@kazlauskas.me>
@nagisa
Copy link
Collaborator

nagisa commented Dec 6, 2022

Thanks! Let me know if I ought to apply the automerge label for you^^

@mina86
Copy link
Contributor Author

mina86 commented Dec 6, 2022

Yeah, will need S-automerge here now.

@mina86
Copy link
Contributor Author

mina86 commented Dec 6, 2022

Let’s pause it actually. I’ve realised it introduces DoS.

@mina86 mina86 closed this Dec 6, 2022
@nagisa
Copy link
Collaborator

nagisa commented Dec 7, 2022

I’ve realised it introduces DoS.

How come? My intuition is that this should be a NFC and I’d be super curious to see where it is that I’m wrong.

@mina86
Copy link
Contributor Author

mina86 commented Dec 7, 2022

The change is in memory_get_vec. My change swapped checking memory access and vector allocation:

     fn memory_get_vec(&mut self, offset: u64, len: u64) -> Result<Vec<u8>> {
         self.gas_counter.pay_base(read_memory_base)?;
         self.gas_counter.pay_per(read_memory_byte, len)?;
-        self.try_fit_mem(offset, len)?;
         let mut buf = vec![0; len as usize];
-        self.memory.read_memory(offset, &mut buf);
+        self.memory.read_memory(offset, &mut buf).map_err(|_| HostError::MemoryAccessViolation)?;
         Ok(buf)
     }

This means that at least theoretically contract could issue a request to read u64::MAX bytes and VMLogic will try to allocate vector of that size (which would result in a panic). The old code would never get to the vector allocation.

There is also gas limit so perhaps this isn’t actually an issue but it’s something that would need to be verified.

@nagisa
Copy link
Collaborator

nagisa commented Dec 7, 2022

Got it. Yeah, this is somewhat nasty. I don’t think the limit is restrictive enough to allocate a vec![] ahead of time, but I think it is probably okay to check for the memory bounds twice for this particular method.

@mina86
Copy link
Contributor Author

mina86 commented Dec 8, 2022

@nagisa, PTAL.

@mina86 mina86 reopened this Dec 8, 2022
Copy link
Collaborator

@nagisa nagisa left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Neat!

@near-bulldozer near-bulldozer bot merged commit 2736d28 into near:master Dec 8, 2022
@mina86 mina86 deleted the b branch December 8, 2022 13:50
nikurt pushed a commit to nikurt/nearcore that referenced this pull request Dec 14, 2022
read_memory and write_memory have to perform the same checks as
fits_memory already does.  So rather than panicking, change the
methods to return an error.  This makes the interface panic-free
and in some situations allows fits_memory call to be skipped.

However, separate fits_memory check may still be necessary so
keep the method but document in detail why it’s needed and, to
keep interfaces consistent, change it to return a Result.

Finally, read_memory_u8 is never used so get rid of it.

While at it, add tests for WasmerMemory.  Essentially copies
of tests from Wasmer2Memory.
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

Successfully merging this pull request may close these issues.

3 participants