Skip to content

Commit efe2dc0

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

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+
## 43.0.2
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
## 43.0.1
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
@@ -502,6 +502,7 @@ impl WastTest {
502502
"misc_testsuite/no-panic.wast",
503503
"misc_testsuite/simple_ref_is_null.wast",
504504
"misc_testsuite/table_grow_with_funcref.wast",
505+
"misc_testsuite/memory64/table-too-big.wast",
505506
"spec_testsuite/br_table.wast",
506507
"spec_testsuite/global.wast",
507508
"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
@@ -309,7 +309,9 @@ unsafe fn alloc_dynamic_table_elements<T>(len: usize) -> Result<Vec<Option<T>>>
309309

310310
let size = mem::size_of::<Option<T>>();
311311
let size = size.next_multiple_of(align);
312-
let size = size.checked_mul(len).unwrap();
312+
let size = size
313+
.checked_mul(len)
314+
.ok_or_else(|| format_err!("overflow calculating table allocation size"))?;
313315

314316
let layout = Layout::from_size_align(size, align)?;
315317

@@ -728,12 +730,15 @@ impl Table {
728730
// that delta is non-zero and the new size doesn't exceed the
729731
// maximum mean we can't get here.
730732
Table::Dynamic(DynamicTable::Func(DynamicFuncTable { elements, .. })) => {
733+
vec_reserve_resize(elements, new_size)?;
731734
elements.resize(new_size, None);
732735
}
733736
Table::Dynamic(DynamicTable::GcRef(DynamicGcRefTable { elements, .. })) => {
737+
vec_reserve_resize(elements, new_size)?;
734738
elements.resize_with(new_size, || None);
735739
}
736740
Table::Dynamic(DynamicTable::Cont(DynamicContTable { elements, .. })) => {
741+
vec_reserve_resize(elements, new_size)?;
737742
elements.resize(new_size, None);
738743
}
739744
}
@@ -1140,3 +1145,10 @@ impl Default for Table {
11401145
})
11411146
}
11421147
}
1148+
1149+
fn vec_reserve_resize<T>(vec: &mut Vec<T>, new_size: usize) -> Result<()> {
1150+
if vec.len() < new_size {
1151+
vec.try_reserve(new_size - vec.len())?;
1152+
}
1153+
Ok(())
1154+
}
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)