From 26bf93ae4c61ceb8f74b7fd28b88622883ba8501 Mon Sep 17 00:00:00 2001 From: lum1n0us Date: Tue, 24 Mar 2026 22:28:27 -0700 Subject: [PATCH] fix: Protect mem consumption from null deref - add debug assertions to wasm_get_module_inst_mem_consumption - add debug assertions to aot_get_module_inst_mem_consumption - nullify memories pointer after free in destruction path - nullify memories pointer after free in AOT destruction - docs: add precondition documentation for memory consumption functions --- .gitignore | 1 + core/iwasm/aot/aot_runtime.c | 20 ++++++++++++++++++++ core/iwasm/interpreter/wasm_runtime.c | 23 ++++++++++++++++++++++- 3 files changed, 43 insertions(+), 1 deletion(-) diff --git a/.gitignore b/.gitignore index 1d14dff9aa..3e6843e195 100644 --- a/.gitignore +++ b/.gitignore @@ -44,3 +44,4 @@ samples/workload/include/** tests/unit/runtime-common/wasm-apps/main.aot tests/unit/aot-stack-frame/wasm-apps/test_aot.h +.worktrees/ diff --git a/core/iwasm/aot/aot_runtime.c b/core/iwasm/aot/aot_runtime.c index 7f57b1adf5..92355f330d 100644 --- a/core/iwasm/aot/aot_runtime.c +++ b/core/iwasm/aot/aot_runtime.c @@ -966,6 +966,7 @@ memories_deinstantiate(AOTModuleInstance *module_inst) } } wasm_runtime_free(module_inst->memories); + module_inst->memories = NULL; } static AOTMemoryInstance * @@ -3795,6 +3796,20 @@ aot_get_module_mem_consumption(const AOTModule *module, mem_conspn->total_size += mem_conspn->aot_code_size; } +/** + * Calculate memory consumption of an AOT module instance. + * + * @param module_inst pointer to a fully initialized AOT module instance + * @param mem_conspn output structure to store memory consumption details + * + * @pre module_inst != NULL + * @pre module_inst->module != NULL + * @pre module_inst->e != NULL + * @pre (module_inst->memory_count == 0) || (module_inst->memories != NULL) + * + * In debug builds, these preconditions are validated with bh_assert. + * In release builds, violating preconditions results in undefined behavior. + */ void aot_get_module_inst_mem_consumption(const AOTModuleInstance *module_inst, WASMModuleInstMemConsumption *mem_conspn) @@ -3802,6 +3817,11 @@ aot_get_module_inst_mem_consumption(const AOTModuleInstance *module_inst, AOTTableInstance *tbl_inst; uint32 i; + bh_assert(module_inst); + bh_assert(module_inst->module); + bh_assert(module_inst->e); + bh_assert(!module_inst->memory_count || module_inst->memories); + memset(mem_conspn, 0, sizeof(*mem_conspn)); mem_conspn->module_inst_struct_size = sizeof(AOTModuleInstance); diff --git a/core/iwasm/interpreter/wasm_runtime.c b/core/iwasm/interpreter/wasm_runtime.c index e41cb4d8e8..b27f52efc3 100644 --- a/core/iwasm/interpreter/wasm_runtime.c +++ b/core/iwasm/interpreter/wasm_runtime.c @@ -3445,9 +3445,11 @@ wasm_deinstantiate(WASMModuleInstance *module_inst, bool is_sub_inst) (WASMModuleInstanceCommon *)module_inst); #endif - if (module_inst->memory_count > 0) + if (module_inst->memory_count > 0) { memories_deinstantiate(module_inst, module_inst->memories, module_inst->memory_count); + module_inst->memories = NULL; + } if (module_inst->import_func_ptrs) { wasm_runtime_free(module_inst->import_func_ptrs); @@ -4227,6 +4229,20 @@ wasm_get_module_mem_consumption(const WASMModule *module, mem_conspn->total_size += mem_conspn->const_strs_size; } +/** + * Calculate memory consumption of a WASM module instance. + * + * @param module_inst pointer to a fully initialized WASM module instance + * @param mem_conspn output structure to store memory consumption details + * + * @pre module_inst != NULL + * @pre module_inst->module != NULL + * @pre module_inst->e != NULL + * @pre (module_inst->memory_count == 0) || (module_inst->memories != NULL) + * + * In debug builds, these preconditions are validated with bh_assert. + * In release builds, violating preconditions results in undefined behavior. + */ void wasm_get_module_inst_mem_consumption(const WASMModuleInstance *module_inst, WASMModuleInstMemConsumption *mem_conspn) @@ -4234,6 +4250,11 @@ wasm_get_module_inst_mem_consumption(const WASMModuleInstance *module_inst, uint32 i; uint64 size; + bh_assert(module_inst); + bh_assert(module_inst->module); + bh_assert(module_inst->e); + bh_assert(!module_inst->memory_count || module_inst->memories); + memset(mem_conspn, 0, sizeof(*mem_conspn)); mem_conspn->module_inst_struct_size = (uint8 *)module_inst->e