Skip to content

Commit 8d6e1e1

Browse files
feat: correct memory trapping behaviour
Signed-off-by: Henry Gressmann <[email protected]>
1 parent e85771c commit 8d6e1e1

File tree

6 files changed

+47
-22
lines changed

6 files changed

+47
-22
lines changed

crates/tinywasm/src/error.rs

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,14 @@ pub enum Trap {
1313
Unreachable,
1414

1515
/// An out-of-bounds memory access occurred
16-
MemoryOutOfBounds,
16+
MemoryOutOfBounds {
17+
/// The offset of the access
18+
offset: usize,
19+
/// The size of the access
20+
len: usize,
21+
/// The maximum size of the memory
22+
max: usize,
23+
},
1724

1825
/// A division by zero occurred
1926
DivisionByZero,

crates/tinywasm/src/runtime/executor/macros.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,8 @@ macro_rules! mem_load {
3535
/// Store a value to memory
3636
macro_rules! mem_store {
3737
($type:ty, $arg:ident, $stack:ident, $store:ident, $module:ident) => {{
38+
log::debug!("mem_store!({}, {:?})", stringify!($type), $arg);
39+
3840
mem_store!($type, $type, $arg, $stack, $store, $module)
3941
}};
4042

crates/tinywasm/src/runtime/executor/mod.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -238,7 +238,7 @@ fn exec_one(
238238

239239
EndFunc => {
240240
debug_assert!(
241-
cf.labels.len() > 0,
241+
cf.labels.len() == 0,
242242
"endfunc: block frames not empty, this should have been validated by the parser"
243243
);
244244

crates/tinywasm/src/store.rs

Lines changed: 32 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -337,7 +337,7 @@ impl TableInstance {
337337
}
338338
}
339339

340-
pub(crate) const PAGE_SIZE: usize = 64_000;
340+
pub(crate) const PAGE_SIZE: usize = 65536;
341341
pub(crate) const MAX_PAGES: usize = 65536;
342342
pub(crate) const MAX_SIZE: usize = PAGE_SIZE * MAX_PAGES;
343343

@@ -366,35 +366,51 @@ impl MemoryInstance {
366366
}
367367

368368
pub(crate) fn store(&mut self, addr: usize, _align: usize, data: &[u8]) -> Result<()> {
369-
if addr + data.len() > self.data.len() {
370-
return Err(Error::Other(format!(
371-
"memory store out of bounds: offset={}, len={}, mem_size={}",
372-
addr,
373-
data.len(),
374-
self.data.len()
375-
)));
369+
let end = addr.checked_add(data.len()).ok_or_else(|| {
370+
Error::Trap(crate::Trap::MemoryOutOfBounds {
371+
offset: addr,
372+
len: data.len(),
373+
max: self.data.len(),
374+
})
375+
})?;
376+
377+
if end > self.data.len() || end < addr {
378+
return Err(Error::Trap(crate::Trap::MemoryOutOfBounds {
379+
offset: addr,
380+
len: data.len(),
381+
max: self.data.len(),
382+
}));
376383
}
377384

378385
// WebAssembly doesn't require alignment for stores
379-
self.data[addr..addr + data.len()].copy_from_slice(data);
386+
self.data[addr..end].copy_from_slice(data);
380387
Ok(())
381388
}
382389

383390
pub(crate) fn load(&self, addr: usize, _align: usize, len: usize) -> Result<&[u8]> {
384-
if addr + len > self.data.len() {
385-
return Err(Error::Other(format!(
386-
"memory load out of bounds: offset={}, len={}, mem_size={}",
387-
addr,
391+
let end = addr.checked_add(len).ok_or_else(|| {
392+
Error::Trap(crate::Trap::MemoryOutOfBounds {
393+
offset: addr,
394+
len,
395+
max: self.data.len(),
396+
})
397+
})?;
398+
399+
if end > self.data.len() {
400+
return Err(Error::Trap(crate::Trap::MemoryOutOfBounds {
401+
offset: addr,
388402
len,
389-
self.data.len()
390-
)));
403+
max: self.data.len(),
404+
}));
391405
}
392406

393407
// WebAssembly doesn't require alignment for loads
394-
Ok(&self.data[addr..addr + len])
408+
Ok(&self.data[addr..end])
395409
}
396410

397411
pub(crate) fn size(&self) -> i32 {
412+
log::debug!("memory pages: {}", self.page_count);
413+
log::debug!("memory size: {}", self.page_count * PAGE_SIZE);
398414
self.page_count as i32
399415
}
400416

0 commit comments

Comments
 (0)