summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorHenry <mail@henrygressmann.de>2026-04-12 15:54:26 +0200
committerHenry <mail@henrygressmann.de>2026-04-12 15:54:26 +0200
commit1fc0be742d623309fe61be172137111c035225e4 (patch)
treefb39e3d76945ee9a123a66f567a723e4eac8cbdc
parent2c349979a3459d44be830a7983b0ccd7a0d3afa4 (diff)
fix: fix unchecked memory offsets causing issues on 32 bit
Signed-off-by: Henry <mail@henrygressmann.de>
-rw-r--r--crates/tinywasm/src/interpreter/executor.rs28
1 files changed, 24 insertions, 4 deletions
diff --git a/crates/tinywasm/src/interpreter/executor.rs b/crates/tinywasm/src/interpreter/executor.rs
index 9218ede..d2eee68 100644
--- a/crates/tinywasm/src/interpreter/executor.rs
+++ b/crates/tinywasm/src/interpreter/executor.rs
@@ -8,9 +8,9 @@ use alloc::{rc::Rc, string::ToString};
use interpreter::stack::CallFrame;
use tinywasm_types::*;
-use super::ExecState;
use super::num_helpers::*;
use super::values::*;
+use super::ExecState;
use crate::engine::FuelPolicy;
use crate::instance::ModuleInstanceInner;
use crate::interpreter::Value128;
@@ -854,7 +854,13 @@ impl<'store, const BUDGETED: bool> Executor<'store, BUDGETED> {
let mem = self.store.state.get_mem_mut(self.module.resolve_mem_addr(memarg.mem_addr()));
let addr = u64::from(self.store.stack.values.local_get::<u32>(&self.cf, u16::from(addr_local)));
let value = cast(self.store.stack.values.local_get::<T>(&self.cf, u16::from(value_local))).to_mem_bytes();
- mem.store((memarg.offset() + addr) as usize, value.len(), &value)?;
+ let Some(effective_addr) = memarg.offset().checked_add(addr) else {
+ return Err(Error::Trap(Trap::MemoryOutOfBounds { offset: addr as usize, len: N, max: 0 }));
+ };
+ let Ok(effective_addr) = usize::try_from(effective_addr) else {
+ return Err(Error::Trap(Trap::MemoryOutOfBounds { offset: addr as usize, len: N, max: 0 }));
+ };
+ mem.store(effective_addr, value.len(), &value)?;
Ok(())
}
@@ -1067,7 +1073,14 @@ impl<'store, const BUDGETED: bool> Executor<'store, BUDGETED> {
false => self.store.stack.values.pop::<i32>() as u32 as u64,
};
- mem.store((offset + addr) as usize, val.len(), &val)?;
+ let Some(effective_addr) = offset.checked_add(addr) else {
+ return Err(Error::Trap(Trap::MemoryOutOfBounds { offset: addr as usize, len: N, max: 0 }));
+ };
+ let Ok(effective_addr) = usize::try_from(effective_addr) else {
+ return Err(Error::Trap(Trap::MemoryOutOfBounds { offset: addr as usize, len: N, max: 0 }));
+ };
+
+ mem.store(effective_addr, val.len(), &val)?;
Ok(())
}
@@ -1087,7 +1100,14 @@ impl<'store, const BUDGETED: bool> Executor<'store, BUDGETED> {
false => u64::from(self.store.stack.values.pop::<i32>() as u32),
};
- mem.store((offset + addr) as usize, val.len(), &val)?;
+ let Some(effective_addr) = offset.checked_add(addr) else {
+ return Err(Error::Trap(Trap::MemoryOutOfBounds { offset: addr as usize, len: N, max: 0 }));
+ };
+ let Ok(effective_addr) = usize::try_from(effective_addr) else {
+ return Err(Error::Trap(Trap::MemoryOutOfBounds { offset: addr as usize, len: N, max: 0 }));
+ };
+
+ mem.store(effective_addr, val.len(), &val)?;
Ok(())
}