Merge pull request #2617 from alexcrichton/limit-tables-and-memeories
Add knobs to limit memories/tables in a `Store`
This commit is contained in:
@@ -34,6 +34,8 @@ pub struct Config {
|
||||
pub(crate) features: WasmFeatures,
|
||||
pub(crate) wasm_backtrace_details_env_used: bool,
|
||||
pub(crate) max_instances: usize,
|
||||
pub(crate) max_tables: usize,
|
||||
pub(crate) max_memories: usize,
|
||||
}
|
||||
|
||||
impl Config {
|
||||
@@ -81,6 +83,8 @@ impl Config {
|
||||
..WasmFeatures::default()
|
||||
},
|
||||
max_instances: 10_000,
|
||||
max_tables: 10_000,
|
||||
max_memories: 10_000,
|
||||
};
|
||||
ret.wasm_backtrace_details(WasmBacktraceDetails::Environment);
|
||||
return ret;
|
||||
@@ -655,11 +659,35 @@ impl Config {
|
||||
/// this `Store`.
|
||||
///
|
||||
/// Instantiation will fail with an error if this limit is exceeded.
|
||||
///
|
||||
/// This value defaults to 10,000.
|
||||
pub fn max_instances(&mut self, instances: usize) -> &mut Self {
|
||||
self.max_instances = instances;
|
||||
self
|
||||
}
|
||||
|
||||
/// Configures the maximum number of tables which can be created within
|
||||
/// this `Store`.
|
||||
///
|
||||
/// Instantiation will fail with an error if this limit is exceeded.
|
||||
///
|
||||
/// This value defaults to 10,000.
|
||||
pub fn max_tables(&mut self, tables: usize) -> &mut Self {
|
||||
self.max_tables = tables;
|
||||
self
|
||||
}
|
||||
|
||||
/// Configures the maximum number of memories which can be created within
|
||||
/// this `Store`.
|
||||
///
|
||||
/// Instantiation will fail with an error if this limit is exceeded.
|
||||
///
|
||||
/// This value defaults to 10,000.
|
||||
pub fn max_memories(&mut self, memories: usize) -> &mut Self {
|
||||
self.max_memories = memories;
|
||||
self
|
||||
}
|
||||
|
||||
pub(crate) fn target_isa(&self) -> Box<dyn TargetIsa> {
|
||||
self.isa_flags
|
||||
.clone()
|
||||
|
||||
@@ -257,7 +257,7 @@ impl<'a> Instantiator<'a> {
|
||||
/// defined here.
|
||||
fn step(&mut self) -> Result<Option<(StoreInstanceHandle, Option<RuntimeInstance>)>> {
|
||||
if self.cur.initializer == 0 {
|
||||
self.store.bump_instance_count()?;
|
||||
self.store.bump_resource_counts(&self.cur.module)?;
|
||||
}
|
||||
|
||||
// Read the current module's initializer and move forward the
|
||||
|
||||
@@ -67,8 +67,11 @@ pub(crate) struct StoreInner {
|
||||
/// Set of all compiled modules that we're holding a strong reference to
|
||||
/// the module's code for. This includes JIT functions, trampolines, etc.
|
||||
modules: RefCell<HashSet<ArcModuleCode>>,
|
||||
/// The number of instantiated instances in this store.
|
||||
|
||||
// Numbers of resources instantiated in this store.
|
||||
instance_count: Cell<usize>,
|
||||
memory_count: Cell<usize>,
|
||||
table_count: Cell<usize>,
|
||||
}
|
||||
|
||||
struct HostInfoKey(VMExternRef);
|
||||
@@ -112,6 +115,8 @@ impl Store {
|
||||
frame_info: Default::default(),
|
||||
modules: Default::default(),
|
||||
instance_count: Default::default(),
|
||||
memory_count: Default::default(),
|
||||
table_count: Default::default(),
|
||||
}),
|
||||
}
|
||||
}
|
||||
@@ -217,12 +222,40 @@ impl Store {
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate) fn bump_instance_count(&self) -> Result<()> {
|
||||
let n = self.inner.instance_count.get();
|
||||
self.inner.instance_count.set(n + 1);
|
||||
if n >= self.engine().config().max_instances {
|
||||
bail!("instance limit of {} exceeded", n);
|
||||
pub(crate) fn bump_resource_counts(&self, module: &Module) -> Result<()> {
|
||||
let config = self.engine().config();
|
||||
|
||||
fn bump(slot: &Cell<usize>, max: usize, amt: usize, desc: &str) -> Result<()> {
|
||||
let new = slot.get().saturating_add(amt);
|
||||
if new > max {
|
||||
bail!(
|
||||
"resource limit exceeded: {} count too high at {}",
|
||||
desc,
|
||||
new
|
||||
);
|
||||
}
|
||||
slot.set(new);
|
||||
Ok(())
|
||||
}
|
||||
|
||||
let module = module.env_module();
|
||||
let memories = module.memory_plans.len() - module.num_imported_memories;
|
||||
let tables = module.table_plans.len() - module.num_imported_tables;
|
||||
|
||||
bump(
|
||||
&self.inner.instance_count,
|
||||
config.max_instances,
|
||||
1,
|
||||
"instance",
|
||||
)?;
|
||||
bump(
|
||||
&self.inner.memory_count,
|
||||
config.max_memories,
|
||||
memories,
|
||||
"memory",
|
||||
)?;
|
||||
bump(&self.inner.table_count, config.max_tables, tables, "table")?;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user