Skip to content

Commit f794a59

Browse files
authored
Avoid out-of-bounds imports read in wasm_instance_new (#2797)
ASan, instantiating a 2-import module through the wasm C API with a 1-element imports vector: ==ERROR: AddressSanitizer: heap-buffer-overflow READ of size 8 ... in wasm_instance_new interp-wasm-c-api.cc:746 0 bytes after 8-byte region [...] (the caller's imports array) Spotted while running modules through libwasm with a fixed imports list. `wasm_instance_new` copies the imports into a `RefVec` by looping `i` over the module's declared import count and reading `imports->data[i]`. Nothing checks the caller actually supplied that many, so a module whose import section declares more imports than the embedder passes reads past the end of the imports array and then derefs the wild pointer through `->I->self()`. `Instance::Instantiate` already rejects a short list with a "not enough imports!" trap, but it runs after this loop, so the over-read happens first. Bounding the loop by `imports->size` lets the short case fall through to that existing trap instead. Valid and over-supplied lists build the same `RefVec` as before.
1 parent 2a8dc8b commit f794a59

1 file changed

Lines changed: 10 additions & 1 deletion

File tree

src/interp/interp-wasm-c-api.cc

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -741,8 +741,17 @@ own wasm_instance_t* wasm_instance_new(wasm_store_t* store,
741741
assert(module);
742742
assert(store);
743743

744+
// The caller must supply exactly as many imports as the module declares;
745+
// reading imports->data[i] beyond imports->size would be out of bounds.
746+
size_t import_count = module->As<Module>()->import_types().size();
747+
if (imports->size != import_count) {
748+
*trap_out = new wasm_trap_t{
749+
Trap::New(store->I, "wrong number of imports provided")};
750+
return nullptr;
751+
}
752+
744753
RefVec import_refs;
745-
for (size_t i = 0; i < module->As<Module>()->import_types().size(); i++) {
754+
for (size_t i = 0; i < import_count; i++) {
746755
import_refs.push_back(imports->data[i]->I->self());
747756
}
748757

0 commit comments

Comments
 (0)