Skip to content

Commit 82baada

Browse files
authored
Fix panicking overflow when calculating table sizes (#13242)
Return an error instead of panicking in the same manner that OOM is handled.
1 parent 0953908 commit 82baada

4 files changed

Lines changed: 42 additions & 1 deletion

File tree

RELEASES.md

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,14 @@
1+
## 36.0.8
2+
3+
Released 2026-04-30.
4+
5+
### Fixed
6+
7+
* Panic when allocating a table exceeding the size of the host's address space.
8+
[GHSA-p8xm-42r7-89xg](https://github.com/bytecodealliance/wasmtime/security/advisories/GHSA-p8xm-42r7-89xg)
9+
10+
--------------------------------------------------------------------------------
11+
112
## 36.0.7
213

314
Released 2026-04-09.

crates/test-util/src/wast.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -432,6 +432,7 @@ impl WastTest {
432432
"misc_testsuite/no-panic.wast",
433433
"misc_testsuite/simple_ref_is_null.wast",
434434
"misc_testsuite/table_grow_with_funcref.wast",
435+
"misc_testsuite/memory64/table-too-big.wast",
435436
"spec_testsuite/br_table.wast",
436437
"spec_testsuite/global.wast",
437438
"spec_testsuite/ref_func.wast",

crates/wasmtime/src/runtime/vm/table.rs

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -408,7 +408,9 @@ unsafe fn alloc_dynamic_table_elements<T>(len: usize) -> Result<Vec<Option<T>>>
408408

409409
let size = mem::size_of::<Option<T>>();
410410
let size = size.next_multiple_of(align);
411-
let size = size.checked_mul(len).unwrap();
411+
let size = size
412+
.checked_mul(len)
413+
.ok_or_else(|| format_err!("overflow calculating table allocation size"))?;
412414

413415
let layout = Layout::from_size_align(size, align)?;
414416

@@ -826,12 +828,15 @@ impl Table {
826828
// that delta is non-zero and the new size doesn't exceed the
827829
// maximum mean we can't get here.
828830
Table::Dynamic(DynamicTable::Func(DynamicFuncTable { elements, .. })) => {
831+
vec_reserve_resize(elements, new_size)?;
829832
elements.resize(new_size, None);
830833
}
831834
Table::Dynamic(DynamicTable::GcRef(DynamicGcRefTable { elements, .. })) => {
835+
vec_reserve_resize(elements, new_size)?;
832836
elements.resize_with(new_size, || None);
833837
}
834838
Table::Dynamic(DynamicTable::Cont(DynamicContTable { elements, .. })) => {
839+
vec_reserve_resize(elements, new_size)?;
835840
elements.resize(new_size, None);
836841
}
837842
}
@@ -1230,3 +1235,10 @@ impl Default for Table {
12301235
})
12311236
}
12321237
}
1238+
1239+
fn vec_reserve_resize<T>(vec: &mut Vec<T>, new_size: usize) -> Result<()> {
1240+
if vec.len() < new_size {
1241+
vec.try_reserve(new_size - vec.len())?;
1242+
}
1243+
Ok(())
1244+
}
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
;;! memory64 = true
2+
;;! hogs_memory = true
3+
;;! reference_types = true
4+
5+
(assert_trap
6+
(module (table i64 0x2000_0000_0000_0000 funcref))
7+
"overflow calculating table allocation size")
8+
9+
(module
10+
(table i64 0 funcref)
11+
(func (export "grow") (param i64) (result i64)
12+
(table.grow 0 (ref.null func) (local.get 0))
13+
)
14+
)
15+
16+
(assert_trap (invoke "grow" (i64.const 0x2000_0000_0000_0000))
17+
"memory allocation failed")

0 commit comments

Comments
 (0)