diff --git a/crates/runtime/src/lib.rs b/crates/runtime/src/lib.rs index 4f531d4220..6fc8e66c3d 100644 --- a/crates/runtime/src/lib.rs +++ b/crates/runtime/src/lib.rs @@ -90,24 +90,28 @@ pub unsafe trait Store { &mut self, ) -> (&mut VMExternRefActivationsTable, &dyn ModuleInfoLookup); - /// Callback invoked to allow the store's resource limiter to reject a memory grow operation. + /// Callback invoked to allow the store's resource limiter to reject a + /// memory grow operation. fn memory_growing( &mut self, current: usize, desired: usize, maximum: Option, ) -> Result; - /// Callback invoked to notify the store's resource limiter that a memory grow operation has - /// failed. + /// Callback invoked to notify the store's resource limiter that a memory + /// grow operation has failed. fn memory_grow_failed(&mut self, error: &Error); - /// Callback invoked to allow the store's resource limiter to reject a table grow operation. + /// Callback invoked to allow the store's resource limiter to reject a + /// table grow operation. fn table_growing( &mut self, current: u32, desired: u32, maximum: Option, ) -> Result; - + /// Callback invoked to notify the store's resource limiter that a table + /// grow operation has failed. + fn table_grow_failed(&mut self, error: &Error); /// Callback invoked whenever fuel runs out by a wasm instance. If an error /// is returned that's raised as a trap. Otherwise wasm execution will /// continue as normal. diff --git a/crates/runtime/src/table.rs b/crates/runtime/src/table.rs index 7e927700ed..53a1f8b7b3 100644 --- a/crates/runtime/src/table.rs +++ b/crates/runtime/src/table.rs @@ -4,8 +4,7 @@ use crate::vmcontext::{VMCallerCheckedAnyfunc, VMTableDefinition}; use crate::{Store, Trap, VMExternRef}; -use anyhow::Error; -use anyhow::{bail, Result}; +use anyhow::{bail, format_err, Error, Result}; use std::convert::{TryFrom, TryInto}; use std::ops::Range; use std::ptr; @@ -302,6 +301,7 @@ impl Table { if let Some(max) = self.maximum() { if new_size > max { + store.table_grow_failed(&format_err!("Table maximum size exceeded")); return Ok(None); } } diff --git a/crates/wasmtime/src/limits.rs b/crates/wasmtime/src/limits.rs index acca7dad4e..02d6fcd814 100644 --- a/crates/wasmtime/src/limits.rs +++ b/crates/wasmtime/src/limits.rs @@ -50,6 +50,13 @@ pub trait ResourceLimiter { /// effect as the table will not grow. fn table_growing(&mut self, current: u32, desired: u32, maximum: Option) -> bool; + /// Notifies the resource limiter that growing a linear memory, permitted by + /// the `table_growing` method, has failed. + /// + /// Reasons for failure include: the growth exceeds the `maximum` passed to + /// `table_growing`. This could expand in the future. + fn table_grow_failed(&mut self, _error: &anyhow::Error) {} + /// The maximum number of instances that can be created for a `Store`. /// /// Module instantiation will fail if this limit is exceeded. @@ -79,9 +86,13 @@ pub trait ResourceLimiter { } #[cfg(feature = "async")] -/// Used by hosts to limit resource consumption of instances. -/// Identical to [`ResourceLimiter`], except that the `memory_growing` and `table_growing` +/// Used by hosts to limit resource consumption of instances. Identical to +/// [`ResourceLimiter`], except that the `memory_growing` and `table_growing` /// functions are async. Must be used with an async [`Store`]. +/// +/// This trait is used with [`Store::limiter_async`]: see those docs for +/// restrictions on using other Wasmtime interfaces with an async resource +/// limiter. #[async_trait::async_trait] pub trait ResourceLimiterAsync { /// Async version of [`ResourceLimiter::memory_growing`] @@ -98,6 +109,9 @@ pub trait ResourceLimiterAsync { /// Asynchronous version of [`ResourceLimiter::table_growing`] async fn table_growing(&mut self, current: u32, desired: u32, maximum: Option) -> bool; + /// Identical to [`ResourceLimiter::table_grow_failed`] + fn table_grow_failed(&mut self, _error: &anyhow::Error) {} + /// Identical to [`ResourceLimiter::instances`]` fn instances(&self) -> usize { DEFAULT_INSTANCE_LIMIT diff --git a/crates/wasmtime/src/store.rs b/crates/wasmtime/src/store.rs index ccacd816e3..44ae7fe3f9 100644 --- a/crates/wasmtime/src/store.rs +++ b/crates/wasmtime/src/store.rs @@ -1618,6 +1618,19 @@ unsafe impl wasmtime_runtime::Store for StoreInner { } } + fn table_grow_failed(&mut self, error: &anyhow::Error) { + match self.limiter { + Some(ResourceLimiterInner::Sync(ref mut limiter)) => { + limiter(&mut self.data).table_grow_failed(error) + } + #[cfg(feature = "async")] + Some(ResourceLimiterInner::Async(ref mut limiter)) => { + limiter(&mut self.data).table_grow_failed(error) + } + None => {} + } + } + fn out_of_gas(&mut self) -> Result<(), anyhow::Error> { return match &mut self.out_of_gas_behavior { OutOfGas::Trap => Err(anyhow::Error::new(OutOfGasError)),