Enhance wasm loader to fix some security issues (#91)

* Implement memory profiler, optimize memory usage, modify code indent

* Implement memory.grow and limit heap space base offset to 1G; modify iwasm build type to Release and 64 bit by default

* Add a new extension library: connection

* Fix bug of reading magic number and version in big endian platform

* Re-org platform APIs: move most platform APIs from iwasm to shared-lib

* Enhance wasm loader to fix some security issues
This commit is contained in:
wenyongh 2019-08-08 16:53:56 +08:00 committed by GitHub
parent 3b19306869
commit 3f15fb3424
5 changed files with 178 additions and 63 deletions

View File

@ -846,6 +846,22 @@ nullFunc_X_wrapper(int32 code)
wasm_runtime_set_exception(module_inst, buf);
}
/*#define ENABLE_SPEC_TEST 1*/
#ifdef ENABLE_SPEC_TEST
static void
print_i32_wrapper(int i32)
{
printf("%d\n", i32);
}
static void
print_wrapper(int i32)
{
printf("%d\n", i32);
}
#endif
/* TODO: add function parameter/result types check */
#define REG_NATIVE_FUNC(module_name, func_name) \
{ #module_name, #func_name, func_name##_wrapper }
@ -857,6 +873,10 @@ typedef struct WASMNativeFuncDef {
} WASMNativeFuncDef;
static WASMNativeFuncDef native_func_defs[] = {
#ifdef ENABLE_SPEC_TEST
REG_NATIVE_FUNC(spectest, print_i32),
REG_NATIVE_FUNC(spectest, print),
#endif
REG_NATIVE_FUNC(env, _printf),
REG_NATIVE_FUNC(env, _sprintf),
REG_NATIVE_FUNC(env, _snprintf),
@ -927,6 +947,9 @@ typedef struct WASMNativeGlobalDef {
} WASMNativeGlobalDef;
static WASMNativeGlobalDef native_global_defs[] = {
#ifdef ENABLE_SPEC_TEST
{ "spectest", "global_i32", .global_data.u32 = 0 },
#endif
{ "env", "STACKTOP", .global_data.u32 = 0 },
{ "env", "STACK_MAX", .global_data.u32 = 0 },
{ "env", "ABORT", .global_data.u32 = 0 },

View File

@ -129,7 +129,11 @@ app_instance_repl(wasm_module_inst_t module_inst)
return NULL;
}
static char global_heap_buf[512 * 1024] = { 0 };
#define USE_GLOBAL_HEAP_BUF 0
#if USE_GLOBAL_HEAP_BUF != 0
static char global_heap_buf[10 * 1024 * 1024] = { 0 };
#endif
int main(int argc, char *argv[])
{
@ -175,11 +179,18 @@ int main(int argc, char *argv[])
app_argc = argc;
app_argv = argv;
#if USE_GLOBAL_HEAP_BUF != 0
if (bh_memory_init_with_pool(global_heap_buf, sizeof(global_heap_buf))
!= 0) {
wasm_printf("Init global heap failed.\n");
wasm_printf("Init memory with global heap buffer failed.\n");
return -1;
}
#else
if (bh_memory_init_with_allocator(malloc, free)) {
wasm_printf("Init memory with memory allocator failed.\n");
return -1;
}
#endif
/* initialize runtime environment */
if (!wasm_runtime_init())
@ -201,8 +212,8 @@ int main(int argc, char *argv[])
/* instantiate the module */
if (!(wasm_module_inst = wasm_runtime_instantiate(wasm_module,
16 * 1024, /* stack size */
8 * 1024, /* heap size */
64 * 1024, /* stack size */
64 * 1024, /* heap size */
error_buf,
sizeof(error_buf)))) {
wasm_printf("%s\n", error_buf);

View File

@ -588,7 +588,7 @@ ALLOC_FRAME(WASMThread *self, uint32 size, WASMInterpFrame *prev_frame)
frame->prev_frame = prev_frame;
else {
wasm_runtime_set_exception(self->module_inst,
"WASM interp failed, alloc frame failed.");
"WASM interp failed: stack overflow.");
}
return frame;
@ -641,7 +641,7 @@ wasm_interp_call_func_native(WASMThread *self,
else {
if (!(argv = wasm_malloc(sizeof(uint32) * argc))) {
wasm_runtime_set_exception(self->module_inst,
"WASM call native failed: alloc memory for argv failed.");
"WASM call native failed: allocate memory failed.");
return;
}
}
@ -768,7 +768,7 @@ wasm_interp_call_func_bytecode(WASMThread *self,
BLOCK_TYPE_BLOCK,
&else_addr, &end_addr,
NULL, 0)) {
wasm_runtime_set_exception(module, "find block addr failed");
wasm_runtime_set_exception(module, "find block address failed");
goto got_exception;
}
@ -783,7 +783,7 @@ wasm_interp_call_func_bytecode(WASMThread *self,
BLOCK_TYPE_LOOP,
&else_addr, &end_addr,
NULL, 0)) {
wasm_runtime_set_exception(module, "find block addr failed");
wasm_runtime_set_exception(module, "find block address failed");
goto got_exception;
}
@ -798,7 +798,7 @@ wasm_interp_call_func_bytecode(WASMThread *self,
BLOCK_TYPE_IF,
&else_addr, &end_addr,
NULL, 0)) {
wasm_runtime_set_exception(module, "find block addr failed");
wasm_runtime_set_exception(module, "find block address failed");
goto got_exception;
}
@ -855,8 +855,9 @@ wasm_interp_call_func_bytecode(WASMThread *self,
depths = depth_buf;
else {
if (!(depths = wasm_malloc(sizeof(uint32) * count))) {
wasm_runtime_set_exception(module, "WASM interp failed, "
"alloc block memory for br_table failed.");
wasm_runtime_set_exception(module,
"WASM interp failed: "
"allocate memory failed.");
goto got_exception;
}
}
@ -931,7 +932,7 @@ wasm_interp_call_func_bytecode(WASMThread *self,
HANDLE_OP (WASM_OP_DROP):
{
wasm_runtime_set_exception(module,
"wasm interp failed: unsupported opcode");
"WASM interp failed: unsupported opcode.");
goto got_exception;
}
@ -950,7 +951,7 @@ wasm_interp_call_func_bytecode(WASMThread *self,
HANDLE_OP (WASM_OP_SELECT):
{
wasm_runtime_set_exception(module,
"wasm interp failed: unsupported opcode");
"WASM interp failed: unsupported opcode.");
goto got_exception;
}
@ -997,7 +998,7 @@ wasm_interp_call_func_bytecode(WASMThread *self,
break;
default:
wasm_runtime_set_exception(module,
"get local type is invalid");
"invalid local type");
goto got_exception;
}
(void)local_count;
@ -1026,7 +1027,7 @@ wasm_interp_call_func_bytecode(WASMThread *self,
break;
default:
wasm_runtime_set_exception(module,
"set local type is invalid");
"invalid local type");
goto got_exception;
}
(void)local_count;
@ -1054,7 +1055,7 @@ wasm_interp_call_func_bytecode(WASMThread *self,
SET_LOCAL_F64(local_idx, GET_F64_FROM_ADDR(frame_sp - 2));
break;
default:
wasm_runtime_set_exception(module, "tee local type is invalid");
wasm_runtime_set_exception(module, "invalid local type");
goto got_exception;
}
(void)local_count;
@ -1085,7 +1086,7 @@ wasm_interp_call_func_bytecode(WASMThread *self,
PUSH_F64(*(float64*)get_global_addr(memory, global));
break;
default:
wasm_runtime_set_exception(module, "get global type is invalid");
wasm_runtime_set_exception(module, "invalid global type");
goto got_exception;
}
HANDLE_OP_END ();
@ -1117,7 +1118,7 @@ wasm_interp_call_func_bytecode(WASMThread *self,
PUT_F64_TO_ADDR((uint32*)global_addr, POP_F64());
break;
default:
wasm_runtime_set_exception(module, "set global index is overflow");
wasm_runtime_set_exception(module, "invalid global type");
goto got_exception;
}
HANDLE_OP_END ();
@ -1977,7 +1978,8 @@ wasm_interp_call_func_bytecode(WASMThread *self,
#if WASM_ENABLE_LABELS_AS_VALUES == 0
default:
wasm_runtime_set_exception(module, "wasm interp failed: unsupported opcode");
wasm_runtime_set_exception(module,
"WASM interp failed: unsupported opcode.");
goto got_exception;
}
#endif
@ -2005,7 +2007,8 @@ wasm_interp_call_func_bytecode(WASMThread *self,
HANDLE_OP (WASM_OP_UNUSED_0x26):
HANDLE_OP (WASM_OP_UNUSED_0x27):
{
wasm_runtime_set_exception(module, "wasm interp failed: unsupported opcode");
wasm_runtime_set_exception(module,
"WASM interp failed: unsupported opcode.");
goto got_exception;
}
#endif

View File

@ -141,7 +141,8 @@ const_str_set_insert(const uint8 *str, int32 len, WASMModule *module,
if (!c_str) {
set_error_buf(error_buf, error_buf_size,
"WASM module load failed: alloc memory failed.");
"WASM module load failed: "
"allocate memory failed.");
return NULL;
}
@ -234,7 +235,7 @@ load_type_section(const uint8 *buf, const uint8 *buf_end, WASMModule *module,
module->type_count = type_count;
if (!(module->types = wasm_malloc(sizeof(WASMType*) * type_count))) {
set_error_buf(error_buf, error_buf_size,
"Load type section failed: alloc memory failed.");
"Load type section failed: allocate memory failed.");
return false;
}
@ -256,13 +257,20 @@ load_type_section(const uint8 *buf, const uint8 *buf_end, WASMModule *module,
CHECK_BUF(p, p_end, param_count);
p += param_count;
read_leb_uint32(p, p_end, result_count);
wasm_assert(result_count <= 1);
if (result_count > 1) {
set_error_buf(error_buf, error_buf_size,
"Load type section failed: invalid result count.");
return false;
}
CHECK_BUF(p, p_end, result_count);
p = p_org;
if (!(type = module->types[i] = wasm_malloc(offsetof(WASMType, types) +
sizeof(uint8) * (param_count + result_count))))
sizeof(uint8) * (param_count + result_count)))) {
set_error_buf(error_buf, error_buf_size,
"Load type section failed: allocate memory failed.");
return false;
}
/* Resolve param types and result types */
type->param_count = param_count;
@ -413,7 +421,7 @@ load_import_section(const uint8 *buf, const uint8 *buf_end, WASMModule *module,
module->import_count = import_count;
if (!(module->imports = wasm_malloc(sizeof(WASMImport) * import_count))) {
set_error_buf(error_buf, error_buf_size,
"Load import section failed: alloc memory failed.");
"Load import section failed: allocate memory failed.");
return false;
}
@ -635,7 +643,7 @@ load_function_section(const uint8 *buf, const uint8 *buf_end,
module->function_count = func_count;
if (!(module->functions = wasm_malloc(sizeof(WASMFunction*) * func_count))) {
set_error_buf(error_buf, error_buf_size,
"Load function section failed: alloc memory failed.");
"Load function section failed: allocate memory failed.");
return false;
}
@ -652,7 +660,8 @@ load_function_section(const uint8 *buf, const uint8 *buf_end,
}
read_leb_uint32(p_code, buf_code_end, code_size);
if (code_size == 0) {
if (code_size == 0
|| p_code + code_size > buf_code_end) {
set_error_buf(error_buf, error_buf_size,
"Load function section failed: "
"invalid function code size.");
@ -678,7 +687,8 @@ load_function_section(const uint8 *buf, const uint8 *buf_end,
if (!(func = module->functions[i] = wasm_malloc(total_size))) {
set_error_buf(error_buf, error_buf_size,
"Load function section failed: alloc memory failed.");
"Load function section failed: "
"allocate memory failed.");
return false;
}
@ -696,7 +706,20 @@ load_function_section(const uint8 *buf, const uint8 *buf_end,
local_type_index = 0;
for (j = 0; j < local_set_count; j++) {
read_leb_uint32(p_code, buf_code_end, sub_local_count);
if (local_type_index + sub_local_count <= local_type_index
|| local_type_index + sub_local_count > local_count) {
set_error_buf(error_buf, error_buf_size,
"Load function section failed: "
"invalid local count.");
return false;
}
read_leb_uint8(p_code, buf_code_end, type);
if (type < VALUE_TYPE_F64 || type > VALUE_TYPE_I32) {
set_error_buf(error_buf, error_buf_size,
"Load function section failed: "
"invalid local type.");
return false;
}
for (k = 0; k < sub_local_count; k++) {
func->local_types[local_type_index++] = type;
}
@ -735,7 +758,8 @@ load_table_section(const uint8 *buf, const uint8 *buf_end, WASMModule *module,
module->table_count = table_count;
if (!(module->tables = wasm_malloc(sizeof(WASMTable) * table_count))) {
set_error_buf(error_buf, error_buf_size,
"Load table section failed: alloc memory failed.");
"Load table section failed: "
"allocate memory failed.");
return false;
}
@ -777,7 +801,8 @@ load_memory_section(const uint8 *buf, const uint8 *buf_end, WASMModule *module,
module->memory_count = memory_count;
if (!(module->memories = wasm_malloc(sizeof(WASMMemory) * memory_count))) {
set_error_buf(error_buf, error_buf_size,
"Load memory section failed: alloc memory failed.");
"Load memory section failed: "
"allocate memory failed.");
return false;
}
@ -814,7 +839,8 @@ load_global_section(const uint8 *buf, const uint8 *buf_end, WASMModule *module,
module->global_count = global_count;
if (!(module->globals = wasm_malloc(sizeof(WASMGlobal) * global_count))) {
set_error_buf(error_buf, error_buf_size,
"Load global section failed: alloc memory failed.");
"Load global section failed: "
"allocate memory failed.");
return false;
}
@ -859,7 +885,8 @@ load_export_section(const uint8 *buf, const uint8 *buf_end, WASMModule *module,
module->export_count = export_count;
if (!(module->exports = wasm_malloc(sizeof(WASMExport) * export_count))) {
set_error_buf(error_buf, error_buf_size,
"Load export section failed: alloc memory failed.");
"Load export section failed: "
"allocate memory failed.");
return false;
}
@ -952,7 +979,7 @@ load_table_segment_section(const uint8 *buf, const uint8 *buf_end, WASMModule *m
(sizeof(WASMTableSeg) * table_segment_count))) {
set_error_buf(error_buf, error_buf_size,
"Load table segment section failed: "
"alloc memory failed.");
"allocate memory failed.");
return false;
}
@ -974,7 +1001,7 @@ load_table_segment_section(const uint8 *buf, const uint8 *buf_end, WASMModule *m
wasm_malloc(sizeof(uint32) * function_count))) {
set_error_buf(error_buf, error_buf_size,
"Load table segment section failed: "
"alloc memory failed.");
"allocate memory failed.");
return false;
}
for (j = 0; j < function_count; j++) {
@ -1012,8 +1039,8 @@ load_data_segment_section(const uint8 *buf, const uint8 *buf_end,
if (!(module->data_segments =
wasm_malloc(sizeof(WASMDataSeg*) * data_seg_count))) {
set_error_buf(error_buf, error_buf_size,
"Load data segment section failed, "
"alloc memory failed.");
"Load data segment section failed: "
"allocate memory failed.");
return false;
}
@ -1031,7 +1058,7 @@ load_data_segment_section(const uint8 *buf, const uint8 *buf_end,
wasm_malloc(sizeof(WASMDataSeg)))) {
set_error_buf(error_buf, error_buf_size,
"Load data segment section failed: "
"alloc memory failed.");
"allocate memory failed.");
return false;
}
@ -1117,12 +1144,6 @@ load_from_sections(WASMModule *module, WASMSection *sections,
section = section->next;
}
if (!buf_code) {
set_error_buf(error_buf, error_buf_size,
"WASM module load failed: find code section failed.");
return false;
}
section = sections;
while (section) {
buf = section->section_body;
@ -1140,6 +1161,11 @@ load_from_sections(WASMModule *module, WASMSection *sections,
return false;
break;
case SECTION_TYPE_FUNC:
if (!buf_code) {
set_error_buf(error_buf, error_buf_size,
"WASM module load failed: find code section failed.");
return false;
}
if (!load_function_section(buf, buf_end, buf_code, buf_code_end,
module, error_buf, error_buf_size))
return false;
@ -1229,7 +1255,8 @@ create_module(char *error_buf, uint32 error_buf_size)
if (!module) {
set_error_buf(error_buf, error_buf_size,
"WASM module load failed: alloc memory failed.");
"WASM module load failed: "
"allocate memory failed.");
return NULL;
}
@ -1309,7 +1336,8 @@ create_sections(const uint8 *buf, uint32 size,
if (!(section = wasm_malloc(sizeof(WASMSection)))) {
set_error_buf(error_buf, error_buf_size,
"WASM module load failed: alloc memory failed.");
"WASM module load failed: "
"allocate memory failed.");
return false;
}
@ -1401,7 +1429,7 @@ wasm_loader_load(const uint8 *buf, uint32 size, char *error_buf, uint32 error_bu
if (!module) {
set_error_buf(error_buf, error_buf_size,
"WASM module load failed: alloc memory failed.");
"WASM module load failed: allocate memory failed.");
return NULL;
}
@ -1855,9 +1883,11 @@ wasm_loader_find_block_addr(WASMModule *module,
break;
default:
LOG_ERROR("WASM loader find block addr failed: invalid opcode %02x.\n",
opcode);
break;
if (error_buf)
snprintf(error_buf, error_buf_size,
"WASM loader find block addr failed: "
"invalid opcode %02x.", opcode);
return false;
}
}
@ -1902,7 +1932,7 @@ memory_realloc(void *mem_old, uint32 size_old, uint32 size_new)
if (!mem_new) { \
set_error_buf(error_buf, error_buf_size, \
"WASM loader prepare bytecode failed: " \
"alloc memory failed"); \
"allocate memory failed."); \
goto fail; \
} \
mem = mem_new; \
@ -2201,6 +2231,24 @@ pop_type(uint8 type, uint8 **p_frame_ref, uint32 *p_stack_cell_num,
} \
} while (0)
static bool
check_memory(WASMModule *module,
char *error_buf, uint32 error_buf_size)
{
if (module->memory_count == 0
&& module->import_memory_count == 0) {
set_error_buf(error_buf, error_buf_size,
"load or store in module without default memory");
return false;
}
return true;
}
#define CHECK_MEMORY() do { \
if (!check_memory(module, error_buf, error_buf_size)) \
goto fail; \
} while (0)
static bool
wasm_loader_prepare_bytecode(WASMModule *module, WASMFunction *func,
char *error_buf, uint32 error_buf_size)
@ -2235,7 +2283,8 @@ wasm_loader_prepare_bytecode(WASMModule *module, WASMFunction *func,
frame_ref_size = 32;
if (!(frame_ref_bottom = frame_ref = wasm_malloc(frame_ref_size))) {
set_error_buf(error_buf, error_buf_size,
"WASM loader prepare bytecode failed: alloc memory failed");
"WASM loader prepare bytecode failed: "
"allocate memory failed");
goto fail;
}
memset(frame_ref_bottom, 0, frame_ref_size);
@ -2244,7 +2293,8 @@ wasm_loader_prepare_bytecode(WASMModule *module, WASMFunction *func,
frame_csp_size = sizeof(BranchBlock) * 8;
if (!(frame_csp_bottom = frame_csp = wasm_malloc(frame_csp_size))) {
set_error_buf(error_buf, error_buf_size,
"WASM loader prepare bytecode failed: alloc memory failed");
"WASM loader prepare bytecode failed: "
"allocate memory failed");
goto fail;
}
@ -2337,7 +2387,7 @@ wasm_loader_prepare_bytecode(WASMModule *module, WASMFunction *func,
if (!block) {
set_error_buf(error_buf, error_buf_size,
"WASM loader prepare bytecode failed: "
"alloc memory failed");
"allocate memory failed.");
goto fail;
}
@ -2350,7 +2400,7 @@ wasm_loader_prepare_bytecode(WASMModule *module, WASMFunction *func,
block)) {
set_error_buf(error_buf, error_buf_size,
"WASM loader prepare bytecode failed: "
"alloc memory failed");
"allocate memory failed.");
wasm_free(block);
goto fail;
}
@ -2482,12 +2532,20 @@ handle_op_br:
WASMType *func_type;
uint32 type_idx;
if (module->table_count == 0
&& module->import_table_count == 0) {
set_error_buf(error_buf, error_buf_size,
"call indirect without default table");
goto fail;
}
read_leb_uint32(p, p_end, type_idx);
read_leb_uint8(p, p_end, u8); /* 0x00 */
POP_I32();
if (type_idx >= module->type_count) {
set_error_buf(error_buf, error_buf_size, "function index is overflow");
set_error_buf(error_buf, error_buf_size,
"function index is overflow");
goto fail;
}
@ -2618,6 +2676,7 @@ handle_op_br:
case WASM_OP_I32_LOAD8_U:
case WASM_OP_I32_LOAD16_S:
case WASM_OP_I32_LOAD16_U:
CHECK_MEMORY();
read_leb_uint32(p, p_end, u32); /* align */
read_leb_uint32(p, p_end, u32); /* offset */
POP_I32();
@ -2631,6 +2690,7 @@ handle_op_br:
case WASM_OP_I64_LOAD16_U:
case WASM_OP_I64_LOAD32_S:
case WASM_OP_I64_LOAD32_U:
CHECK_MEMORY();
read_leb_uint32(p, p_end, u32); /* align */
read_leb_uint32(p, p_end, u32); /* offset */
POP_I32();
@ -2638,6 +2698,7 @@ handle_op_br:
break;
case WASM_OP_F32_LOAD:
CHECK_MEMORY();
read_leb_uint32(p, p_end, u32); /* align */
read_leb_uint32(p, p_end, u32); /* offset */
POP_I32();
@ -2645,6 +2706,7 @@ handle_op_br:
break;
case WASM_OP_F64_LOAD:
CHECK_MEMORY();
read_leb_uint32(p, p_end, u32); /* align */
read_leb_uint32(p, p_end, u32); /* offset */
POP_I32();
@ -2654,6 +2716,7 @@ handle_op_br:
case WASM_OP_I32_STORE:
case WASM_OP_I32_STORE8:
case WASM_OP_I32_STORE16:
CHECK_MEMORY();
read_leb_uint32(p, p_end, u32); /* align */
read_leb_uint32(p, p_end, u32); /* offset */
POP_I32();
@ -2664,6 +2727,7 @@ handle_op_br:
case WASM_OP_I64_STORE8:
case WASM_OP_I64_STORE16:
case WASM_OP_I64_STORE32:
CHECK_MEMORY();
read_leb_uint32(p, p_end, u32); /* align */
read_leb_uint32(p, p_end, u32); /* offset */
POP_I64();
@ -2671,6 +2735,7 @@ handle_op_br:
break;
case WASM_OP_F32_STORE:
CHECK_MEMORY();
read_leb_uint32(p, p_end, u32); /* align */
read_leb_uint32(p, p_end, u32); /* offset */
POP_F32();
@ -2678,6 +2743,7 @@ handle_op_br:
break;
case WASM_OP_F64_STORE:
CHECK_MEMORY();
read_leb_uint32(p, p_end, u32); /* align */
read_leb_uint32(p, p_end, u32); /* offset */
POP_F64();
@ -2685,11 +2751,13 @@ handle_op_br:
break;
case WASM_OP_MEMORY_SIZE:
CHECK_MEMORY();
read_leb_uint32(p, p_end, u32); /* 0x00 */
PUSH_I32();
break;
case WASM_OP_MEMORY_GROW:
CHECK_MEMORY();
read_leb_uint32(p, p_end, u32); /* 0x00 */
POP_I32();
PUSH_I32();
@ -2971,15 +3039,24 @@ handle_op_br:
break;
default:
LOG_ERROR("WASM loader find block addr failed: invalid opcode %02x.\n",
opcode);
break;
if (error_buf != NULL)
snprintf(error_buf, error_buf_size,
"WASM module load failed: "
"invalid opcode %02x.", opcode);
goto fail;
}
if (opcode != WASM_OP_I32_CONST)
is_i32_const = false;
}
if (csp_num > 0) {
set_error_buf(error_buf, error_buf_size,
"WASM module load failed: "
"function body must end with END opcode.");
goto fail;
}
func->max_stack_cell_num = max_stack_cell_num;
func->max_block_num = max_csp_num;
return_value = true;

View File

@ -877,8 +877,9 @@ wasm_runtime_instantiate(WASMModule *module,
length = data_seg->data_length;
memory_size = NumBytesPerPage * module_inst->default_memory->cur_page_count;
if (base_offset >= memory_size
|| base_offset + length > memory_size) {
if (length > 0
&& (base_offset >= memory_size
|| base_offset + length > memory_size)) {
set_error_buf(error_buf, error_buf_size,
"Instantiate module failed: data segment out of range.");
wasm_runtime_deinstantiate(module_inst);