From 4b1a6e5017cb7ffec98a9fa2d8db28d37334a7cf Mon Sep 17 00:00:00 2001 From: Wenyong Huang Date: Mon, 30 Oct 2023 11:07:01 +0800 Subject: [PATCH] Fix repeatedly initialize shared memory data and protect the memory's fields (#2673) Avoid repeatedly initializing the shared memory data when creating the child thread in lib-pthread or lib-wasi-threads. Add shared memory lock when accessing some fields of the memory instance if the memory instance is shared. Init shared memory's memory_data_size/memory_data_end fields according to the current page count but not max page count. Add wasm_runtime_set_mem_bound_check_bytes, and refine the error message when shared memory flag is found but the feature isn't enabled. --- core/iwasm/aot/aot_runtime.c | 89 ++++++++++++--------- core/iwasm/common/wasm_memory.c | 102 +++++++++++++++++------- core/iwasm/common/wasm_memory.h | 4 + core/iwasm/common/wasm_runtime_common.c | 3 +- core/iwasm/common/wasm_runtime_common.h | 8 ++ core/iwasm/common/wasm_shared_memory.c | 5 ++ core/iwasm/interpreter/wasm_loader.c | 10 ++- core/iwasm/interpreter/wasm_runtime.c | 84 ++++++++++--------- 8 files changed, 195 insertions(+), 110 deletions(-) diff --git a/core/iwasm/aot/aot_runtime.c b/core/iwasm/aot/aot_runtime.c index 0799d625f..3b3d2d743 100644 --- a/core/iwasm/aot/aot_runtime.c +++ b/core/iwasm/aot/aot_runtime.c @@ -7,6 +7,7 @@ #include "bh_log.h" #include "mem_alloc.h" #include "../common/wasm_runtime_common.h" +#include "../common/wasm_memory.h" #include "../interpreter/wasm_runtime.h" #if WASM_ENABLE_SHARED_MEMORY != 0 #include "../common/wasm_shared_memory.h" @@ -382,7 +383,7 @@ memory_instantiate(AOTModuleInstance *module_inst, AOTModuleInstance *parent, uint32 inc_page_count, aux_heap_base, global_idx; uint32 bytes_of_last_page, bytes_to_page_end; uint32 heap_offset = num_bytes_per_page * init_page_count; - uint64 total_size; + uint64 memory_data_size, max_memory_data_size; uint8 *p = NULL, *global_addr; #ifdef OS_ENABLE_HW_BOUND_CHECK uint8 *mapped_mem; @@ -496,23 +497,34 @@ memory_instantiate(AOTModuleInstance *module_inst, AOTModuleInstance *parent, module->aux_stack_size); LOG_VERBOSE(" heap offset: %u, heap size: %d\n", heap_offset, heap_size); - total_size = (uint64)num_bytes_per_page * init_page_count; -#if WASM_ENABLE_SHARED_MEMORY != 0 - if (is_shared_memory) { - /* Allocate max page for shared memory */ - total_size = (uint64)num_bytes_per_page * max_page_count; - } -#endif - bh_assert(total_size <= UINT32_MAX); + memory_data_size = (uint64)num_bytes_per_page * init_page_count; + max_memory_data_size = (uint64)num_bytes_per_page * max_page_count; + bh_assert(memory_data_size <= UINT32_MAX); + bh_assert(max_memory_data_size <= 4 * (uint64)BH_GB); + (void)max_memory_data_size; #ifndef OS_ENABLE_HW_BOUND_CHECK - /* Allocate memory */ - if (total_size > 0 - && !(p = runtime_malloc(total_size, error_buf, error_buf_size))) { - return NULL; +#if WASM_ENABLE_SHARED_MEMORY != 0 + if (is_shared_memory) { + /* Allocate maximum memory size when memory is shared */ + if (max_memory_data_size > 0 + && !(p = runtime_malloc(max_memory_data_size, error_buf, + error_buf_size))) { + return NULL; + } } -#else - total_size = (total_size + page_size - 1) & ~(page_size - 1); + else +#endif + { + /* Allocate initial memory size when memory is not shared */ + if (memory_data_size > 0 + && !(p = runtime_malloc(memory_data_size, error_buf, + error_buf_size))) { + return NULL; + } + } +#else /* else of OS_ENABLE_HW_BOUND_CHECK */ + memory_data_size = (memory_data_size + page_size - 1) & ~(page_size - 1); /* Totally 8G is mapped, the opcode load/store address range is 0 to 8G: * ea = i + memarg.offset @@ -526,17 +538,18 @@ memory_instantiate(AOTModuleInstance *module_inst, AOTModuleInstance *parent, } #ifdef BH_PLATFORM_WINDOWS - if (!os_mem_commit(p, total_size, MMAP_PROT_READ | MMAP_PROT_WRITE)) { + if (!os_mem_commit(p, memory_data_size, MMAP_PROT_READ | MMAP_PROT_WRITE)) { set_error_buf(error_buf, error_buf_size, "commit memory failed"); os_munmap(mapped_mem, map_size); return NULL; } #endif - if (os_mprotect(p, total_size, MMAP_PROT_READ | MMAP_PROT_WRITE) != 0) { + if (os_mprotect(p, memory_data_size, MMAP_PROT_READ | MMAP_PROT_WRITE) + != 0) { set_error_buf(error_buf, error_buf_size, "mprotect memory failed"); #ifdef BH_PLATFORM_WINDOWS - os_mem_decommit(p, total_size); + os_mem_decommit(p, memory_data_size); #endif os_munmap(mapped_mem, map_size); return NULL; @@ -545,18 +558,15 @@ memory_instantiate(AOTModuleInstance *module_inst, AOTModuleInstance *parent, * again here */ #endif /* end of OS_ENABLE_HW_BOUND_CHECK */ - if (total_size > UINT32_MAX) - total_size = UINT32_MAX; - memory_inst->module_type = Wasm_Module_AoT; memory_inst->num_bytes_per_page = num_bytes_per_page; memory_inst->cur_page_count = init_page_count; memory_inst->max_page_count = max_page_count; - memory_inst->memory_data_size = (uint32)total_size; + memory_inst->memory_data_size = (uint32)memory_data_size; /* Init memory info */ memory_inst->memory_data = p; - memory_inst->memory_data_end = p + (uint32)total_size; + memory_inst->memory_data_end = p + (uint32)memory_data_size; /* Initialize heap info */ memory_inst->heap_data = p + heap_offset; @@ -579,20 +589,8 @@ memory_instantiate(AOTModuleInstance *module_inst, AOTModuleInstance *parent, } } - if (total_size > 0) { -#if UINTPTR_MAX == UINT64_MAX - memory_inst->mem_bound_check_1byte.u64 = total_size - 1; - memory_inst->mem_bound_check_2bytes.u64 = total_size - 2; - memory_inst->mem_bound_check_4bytes.u64 = total_size - 4; - memory_inst->mem_bound_check_8bytes.u64 = total_size - 8; - memory_inst->mem_bound_check_16bytes.u64 = total_size - 16; -#else - memory_inst->mem_bound_check_1byte.u32[0] = (uint32)total_size - 1; - memory_inst->mem_bound_check_2bytes.u32[0] = (uint32)total_size - 2; - memory_inst->mem_bound_check_4bytes.u32[0] = (uint32)total_size - 4; - memory_inst->mem_bound_check_8bytes.u32[0] = (uint32)total_size - 8; - memory_inst->mem_bound_check_16bytes.u32[0] = (uint32)total_size - 16; -#endif + if (memory_data_size > 0) { + wasm_runtime_set_mem_bound_check_bytes(memory_inst, memory_data_size); } #if WASM_ENABLE_SHARED_MEMORY != 0 @@ -613,7 +611,7 @@ fail1: #else #ifdef BH_PLATFORM_WINDOWS if (memory_inst->memory_data) - os_mem_decommit(p, total_size); + os_mem_decommit(p, memory_data_size); #endif os_munmap(mapped_mem, map_size); #endif @@ -673,6 +671,10 @@ memories_instantiate(AOTModuleInstance *module_inst, AOTModuleInstance *parent, if (data_seg->is_passive) continue; #endif + if (parent != NULL) + /* Ignore setting memory init data if the memory has been + initialized */ + continue; bh_assert(data_seg->offset.init_expr_type == INIT_EXPR_TYPE_I32_CONST || data_seg->offset.init_expr_type @@ -1897,6 +1899,13 @@ aot_module_free_internal(AOTModuleInstance *module_inst, WASMExecEnv *exec_env, if (ptr) { uint8 *addr = memory_inst->memory_data + ptr; + uint8 *memory_data_end; + + /* memory->memory_data_end may be changed in memory grow */ + SHARED_MEMORY_LOCK(memory_inst); + memory_data_end = memory_inst->memory_data_end; + SHARED_MEMORY_UNLOCK(memory_inst); + if (memory_inst->heap_handle && memory_inst->heap_data < addr && addr < memory_inst->heap_data_end) { mem_allocator_free(memory_inst->heap_handle, addr); @@ -1904,7 +1913,7 @@ aot_module_free_internal(AOTModuleInstance *module_inst, WASMExecEnv *exec_env, else if (module->malloc_func_index != (uint32)-1 && module->free_func_index != (uint32)-1 && memory_inst->memory_data <= addr - && addr < memory_inst->memory_data_end) { + && addr < memory_data_end) { AOTFunctionInstance *free_func; char *free_func_name; @@ -2298,7 +2307,9 @@ aot_memory_init(AOTModuleInstance *module_inst, uint32 seg_index, uint32 offset, maddr = wasm_runtime_addr_app_to_native( (WASMModuleInstanceCommon *)module_inst, dst); + SHARED_MEMORY_LOCK(memory_inst); bh_memcpy_s(maddr, memory_inst->memory_data_size - dst, data + offset, len); + SHARED_MEMORY_UNLOCK(memory_inst); return true; } diff --git a/core/iwasm/common/wasm_memory.c b/core/iwasm/common/wasm_memory.c index 05635ef51..cf29afe0e 100644 --- a/core/iwasm/common/wasm_memory.c +++ b/core/iwasm/common/wasm_memory.c @@ -298,10 +298,15 @@ wasm_runtime_validate_app_addr(WASMModuleInstanceCommon *module_inst_comm, goto fail; } + SHARED_MEMORY_LOCK(memory_inst); + if (app_offset + size <= memory_inst->memory_data_size) { + SHARED_MEMORY_UNLOCK(memory_inst); return true; } + SHARED_MEMORY_UNLOCK(memory_inst); + fail: wasm_set_exception(module_inst, "out of bounds memory access"); return false; @@ -364,11 +369,16 @@ wasm_runtime_validate_native_addr(WASMModuleInstanceCommon *module_inst_comm, goto fail; } + SHARED_MEMORY_LOCK(memory_inst); + if (memory_inst->memory_data <= addr && addr + size <= memory_inst->memory_data_end) { + SHARED_MEMORY_UNLOCK(memory_inst); return true; } + SHARED_MEMORY_UNLOCK(memory_inst); + fail: wasm_set_exception(module_inst, "out of bounds memory access"); return false; @@ -393,20 +403,24 @@ wasm_runtime_addr_app_to_native(WASMModuleInstanceCommon *module_inst_comm, return NULL; } + SHARED_MEMORY_LOCK(memory_inst); + addr = memory_inst->memory_data + app_offset; if (bounds_checks) { if (memory_inst->memory_data <= addr && addr < memory_inst->memory_data_end) { - + SHARED_MEMORY_UNLOCK(memory_inst); return addr; } } /* If bounds checks is disabled, return the address directly */ else if (app_offset != 0) { + SHARED_MEMORY_UNLOCK(memory_inst); return addr; } + SHARED_MEMORY_UNLOCK(memory_inst); return NULL; } @@ -418,6 +432,7 @@ wasm_runtime_addr_native_to_app(WASMModuleInstanceCommon *module_inst_comm, WASMMemoryInstance *memory_inst; uint8 *addr = (uint8 *)native_ptr; bool bounds_checks; + uint32 ret; bh_assert(module_inst_comm->module_type == Wasm_Module_Bytecode || module_inst_comm->module_type == Wasm_Module_AoT); @@ -429,16 +444,24 @@ wasm_runtime_addr_native_to_app(WASMModuleInstanceCommon *module_inst_comm, return 0; } + SHARED_MEMORY_LOCK(memory_inst); + if (bounds_checks) { if (memory_inst->memory_data <= addr - && addr < memory_inst->memory_data_end) - return (uint32)(addr - memory_inst->memory_data); + && addr < memory_inst->memory_data_end) { + ret = (uint32)(addr - memory_inst->memory_data); + SHARED_MEMORY_UNLOCK(memory_inst); + return ret; + } } /* If bounds checks is disabled, return the offset directly */ else if (addr != NULL) { - return (uint32)(addr - memory_inst->memory_data); + ret = (uint32)(addr - memory_inst->memory_data); + SHARED_MEMORY_UNLOCK(memory_inst); + return ret; } + SHARED_MEMORY_UNLOCK(memory_inst); return 0; } @@ -459,6 +482,8 @@ wasm_runtime_get_app_addr_range(WASMModuleInstanceCommon *module_inst_comm, return false; } + SHARED_MEMORY_LOCK(memory_inst); + memory_data_size = memory_inst->memory_data_size; if (app_offset < memory_data_size) { @@ -466,9 +491,11 @@ wasm_runtime_get_app_addr_range(WASMModuleInstanceCommon *module_inst_comm, *p_app_start_offset = 0; if (p_app_end_offset) *p_app_end_offset = memory_data_size; + SHARED_MEMORY_UNLOCK(memory_inst); return true; } + SHARED_MEMORY_UNLOCK(memory_inst); return false; } @@ -490,15 +517,19 @@ wasm_runtime_get_native_addr_range(WASMModuleInstanceCommon *module_inst_comm, return false; } + SHARED_MEMORY_LOCK(memory_inst); + if (memory_inst->memory_data <= addr && addr < memory_inst->memory_data_end) { if (p_native_start_addr) *p_native_start_addr = memory_inst->memory_data; if (p_native_end_addr) *p_native_end_addr = memory_inst->memory_data_end; + SHARED_MEMORY_UNLOCK(memory_inst); return true; } + SHARED_MEMORY_UNLOCK(memory_inst); return false; } @@ -512,9 +543,12 @@ wasm_check_app_addr_and_convert(WASMModuleInstance *module_inst, bool is_str, bool bounds_checks; if (!memory_inst) { - goto fail; + wasm_set_exception(module_inst, "out of bounds memory access"); + return false; } + SHARED_MEMORY_LOCK(memory_inst); + native_addr = memory_inst->memory_data + app_buf_addr; bounds_checks = is_bounds_checks_enabled((wasm_module_inst_t)module_inst); @@ -551,12 +585,18 @@ wasm_check_app_addr_and_convert(WASMModuleInstance *module_inst, bool is_str, } #endif + SHARED_MEMORY_UNLOCK(memory_inst); + success: *p_native_addr = (void *)native_addr; return true; + +#ifndef OS_ENABLE_HW_BOUND_CHECK fail: + SHARED_MEMORY_UNLOCK(memory_inst); wasm_set_exception(module_inst, "out of bounds memory access"); return false; +#endif } WASMMemoryInstance * @@ -568,6 +608,27 @@ wasm_get_default_memory(WASMModuleInstance *module_inst) return NULL; } +void +wasm_runtime_set_mem_bound_check_bytes(WASMMemoryInstance *memory, + uint64 memory_data_size) +{ +#if WASM_ENABLE_FAST_JIT != 0 || WASM_ENABLE_JIT != 0 || WASM_ENABLE_AOT != 0 +#if UINTPTR_MAX == UINT64_MAX + memory->mem_bound_check_1byte.u64 = memory_data_size - 1; + memory->mem_bound_check_2bytes.u64 = memory_data_size - 2; + memory->mem_bound_check_4bytes.u64 = memory_data_size - 4; + memory->mem_bound_check_8bytes.u64 = memory_data_size - 8; + memory->mem_bound_check_16bytes.u64 = memory_data_size - 16; +#else + memory->mem_bound_check_1byte.u32[0] = (uint32)memory_data_size - 1; + memory->mem_bound_check_2bytes.u32[0] = (uint32)memory_data_size - 2; + memory->mem_bound_check_4bytes.u32[0] = (uint32)memory_data_size - 4; + memory->mem_bound_check_8bytes.u32[0] = (uint32)memory_data_size - 8; + memory->mem_bound_check_16bytes.u32[0] = (uint32)memory_data_size - 16; +#endif +#endif +} + #ifndef OS_ENABLE_HW_BOUND_CHECK bool wasm_enlarge_memory_internal(WASMModuleInstance *module, uint32 inc_page_count) @@ -625,9 +686,10 @@ wasm_enlarge_memory_internal(WASMModuleInstance *module, uint32 inc_page_count) memory->num_bytes_per_page = num_bytes_per_page; memory->cur_page_count = total_page_count; memory->max_page_count = max_page_count; - /* No need to update memory->memory_data_size as it is - initialized with the maximum memory data size for - shared memory */ + memory->memory_data_size = (uint32)total_size_new; + memory->memory_data_end = memory->memory_data + (uint32)total_size_new; + + wasm_runtime_set_mem_bound_check_bytes(memory, total_size_new); return true; } #endif @@ -679,21 +741,7 @@ wasm_enlarge_memory_internal(WASMModuleInstance *module, uint32 inc_page_count) memory->memory_data = memory_data_new; memory->memory_data_end = memory_data_new + (uint32)total_size_new; -#if WASM_ENABLE_FAST_JIT != 0 || WASM_ENABLE_JIT != 0 || WASM_ENABLE_AOT != 0 -#if UINTPTR_MAX == UINT64_MAX - memory->mem_bound_check_1byte.u64 = total_size_new - 1; - memory->mem_bound_check_2bytes.u64 = total_size_new - 2; - memory->mem_bound_check_4bytes.u64 = total_size_new - 4; - memory->mem_bound_check_8bytes.u64 = total_size_new - 8; - memory->mem_bound_check_16bytes.u64 = total_size_new - 16; -#else - memory->mem_bound_check_1byte.u32[0] = (uint32)total_size_new - 1; - memory->mem_bound_check_2bytes.u32[0] = (uint32)total_size_new - 2; - memory->mem_bound_check_4bytes.u32[0] = (uint32)total_size_new - 4; - memory->mem_bound_check_8bytes.u32[0] = (uint32)total_size_new - 8; - memory->mem_bound_check_16bytes.u32[0] = (uint32)total_size_new - 16; -#endif -#endif + wasm_runtime_set_mem_bound_check_bytes(memory, total_size_new); #if defined(os_writegsbase) /* write base addr of linear memory to GS segment register */ @@ -799,13 +847,7 @@ wasm_enlarge_memory_internal(WASMModuleInstance *module, uint32 inc_page_count) memory->memory_data_size = (uint32)total_size_new; memory->memory_data_end = memory->memory_data + (uint32)total_size_new; -#if WASM_ENABLE_FAST_JIT != 0 || WASM_ENABLE_JIT != 0 || WASM_ENABLE_AOT != 0 - memory->mem_bound_check_1byte.u64 = total_size_new - 1; - memory->mem_bound_check_2bytes.u64 = total_size_new - 2; - memory->mem_bound_check_4bytes.u64 = total_size_new - 4; - memory->mem_bound_check_8bytes.u64 = total_size_new - 8; - memory->mem_bound_check_16bytes.u64 = total_size_new - 16; -#endif + wasm_runtime_set_mem_bound_check_bytes(memory, total_size_new); return_func: if (!ret && enlarge_memory_error_cb) { diff --git a/core/iwasm/common/wasm_memory.h b/core/iwasm/common/wasm_memory.h index daca2b71e..c46b32ea7 100644 --- a/core/iwasm/common/wasm_memory.h +++ b/core/iwasm/common/wasm_memory.h @@ -24,6 +24,10 @@ wasm_runtime_memory_destroy(); unsigned wasm_runtime_memory_pool_size(); +void +wasm_runtime_set_mem_bound_check_bytes(WASMMemoryInstance *memory, + uint64 memory_data_size); + void wasm_runtime_set_enlarge_mem_error_callback( const enlarge_memory_error_callback_t callback, void *user_data); diff --git a/core/iwasm/common/wasm_runtime_common.c b/core/iwasm/common/wasm_runtime_common.c index 031fb539d..36d9c33a6 100644 --- a/core/iwasm/common/wasm_runtime_common.c +++ b/core/iwasm/common/wasm_runtime_common.c @@ -3038,7 +3038,8 @@ wasm_runtime_init_wasi(WASMModuleInstanceCommon *module_inst, } } - strncpy(mapping_copy, map_dir_list[i], strlen(map_dir_list[i]) + 1); + bh_memcpy_s(mapping_copy, max_len, map_dir_list[i], + (uint32)(strlen(map_dir_list[i]) + 1)); map_mapped = strtok(mapping_copy, "::"); map_host = strtok(NULL, "::"); diff --git a/core/iwasm/common/wasm_runtime_common.h b/core/iwasm/common/wasm_runtime_common.h index a834d67f2..4e14ed4a1 100644 --- a/core/iwasm/common/wasm_runtime_common.h +++ b/core/iwasm/common/wasm_runtime_common.h @@ -298,6 +298,14 @@ LOAD_I16(void *addr) #endif /* WASM_CPU_SUPPORTS_UNALIGNED_ADDR_ACCESS != 0 */ +#if WASM_ENABLE_SHARED_MEMORY != 0 +#define SHARED_MEMORY_LOCK(memory) shared_memory_lock(memory) +#define SHARED_MEMORY_UNLOCK(memory) shared_memory_unlock(memory) +#else +#define SHARED_MEMORY_LOCK(memory) (void)0 +#define SHARED_MEMORY_UNLOCK(memory) (void)0 +#endif + typedef struct WASMModuleCommon { /* Module type, for module loaded from WASM bytecode binary, this field is Wasm_Module_Bytecode, and this structure should diff --git a/core/iwasm/common/wasm_shared_memory.c b/core/iwasm/common/wasm_shared_memory.c index c95d4b7ed..d36ca1833 100644 --- a/core/iwasm/common/wasm_shared_memory.c +++ b/core/iwasm/common/wasm_shared_memory.c @@ -301,12 +301,15 @@ wasm_runtime_atomic_wait(WASMModuleInstanceCommon *module, void *address, return -1; } + shared_memory_lock(module_inst->memories[0]); if ((uint8 *)address < module_inst->memories[0]->memory_data || (uint8 *)address + (wait64 ? 8 : 4) > module_inst->memories[0]->memory_data_end) { + shared_memory_unlock(module_inst->memories[0]); wasm_runtime_set_exception(module, "out of bounds memory access"); return -1; } + shared_memory_unlock(module_inst->memories[0]); #if WASM_ENABLE_THREAD_MGR != 0 exec_env = @@ -423,9 +426,11 @@ wasm_runtime_atomic_notify(WASMModuleInstanceCommon *module, void *address, bh_assert(module->module_type == Wasm_Module_Bytecode || module->module_type == Wasm_Module_AoT); + shared_memory_lock(module_inst->memories[0]); out_of_bounds = ((uint8 *)address < module_inst->memories[0]->memory_data || (uint8 *)address + 4 > module_inst->memories[0]->memory_data_end); + shared_memory_unlock(module_inst->memories[0]); if (out_of_bounds) { wasm_runtime_set_exception(module, "out of bounds memory access"); diff --git a/core/iwasm/interpreter/wasm_loader.c b/core/iwasm/interpreter/wasm_loader.c index 4afa1157c..ea2eb70f5 100644 --- a/core/iwasm/interpreter/wasm_loader.c +++ b/core/iwasm/interpreter/wasm_loader.c @@ -1375,7 +1375,15 @@ load_memory(const uint8 **p_buf, const uint8 *buf_end, WASMMemory *memory, return false; } if (memory->flags > 1) { - set_error_buf(error_buf, error_buf_size, "integer too large"); + if (memory->flags & 2) { + set_error_buf(error_buf, error_buf_size, + "shared memory flag was found, " + "please enable shared memory, lib-pthread " + "or lib-wasi-threads"); + } + else { + set_error_buf(error_buf, error_buf_size, "invalid memory flags"); + } return false; } #else diff --git a/core/iwasm/interpreter/wasm_runtime.c b/core/iwasm/interpreter/wasm_runtime.c index 8fb19d52e..d89470652 100644 --- a/core/iwasm/interpreter/wasm_runtime.c +++ b/core/iwasm/interpreter/wasm_runtime.c @@ -10,6 +10,7 @@ #include "bh_log.h" #include "mem_alloc.h" #include "../common/wasm_runtime_common.h" +#include "../common/wasm_memory.h" #if WASM_ENABLE_SHARED_MEMORY != 0 #include "../common/wasm_shared_memory.h" #endif @@ -167,7 +168,7 @@ memory_instantiate(WASMModuleInstance *module_inst, WASMModuleInstance *parent, char *error_buf, uint32 error_buf_size) { WASMModule *module = module_inst->module; - uint64 memory_data_size; + uint64 memory_data_size, max_memory_data_size; uint32 heap_offset = num_bytes_per_page * init_page_count; uint32 inc_page_count, aux_heap_base, global_idx; uint32 bytes_of_last_page, bytes_to_page_end; @@ -282,22 +283,33 @@ memory_instantiate(WASMModuleInstance *module_inst, WASMModuleInstance *parent, LOG_VERBOSE(" heap offset: %u, heap size: %d\n", heap_offset, heap_size); memory_data_size = (uint64)num_bytes_per_page * init_page_count; -#if WASM_ENABLE_SHARED_MEMORY != 0 - if (is_shared_memory) { - /* Allocate max page for shared memory */ - memory_data_size = (uint64)num_bytes_per_page * max_page_count; - } -#endif - bh_assert(memory_data_size <= 4 * (uint64)BH_GB); + max_memory_data_size = (uint64)num_bytes_per_page * max_page_count; + bh_assert(memory_data_size <= UINT32_MAX); + bh_assert(max_memory_data_size <= 4 * (uint64)BH_GB); + (void)max_memory_data_size; bh_assert(memory != NULL); #ifndef OS_ENABLE_HW_BOUND_CHECK - if (memory_data_size > 0 - && !(memory->memory_data = - runtime_malloc(memory_data_size, error_buf, error_buf_size))) { - goto fail1; +#if WASM_ENABLE_SHARED_MEMORY != 0 + if (is_shared_memory) { + /* Allocate maximum memory size when memory is shared */ + if (max_memory_data_size > 0 + && !(memory->memory_data = runtime_malloc( + max_memory_data_size, error_buf, error_buf_size))) { + goto fail1; + } } -#else + else +#endif + { + /* Allocate initial memory size when memory is not shared */ + if (memory_data_size > 0 + && !(memory->memory_data = runtime_malloc( + memory_data_size, error_buf, error_buf_size))) { + goto fail1; + } + } +#else /* else of OS_ENABLE_HW_BOUND_CHECK */ memory_data_size = (memory_data_size + page_size - 1) & ~(page_size - 1); /* Totally 8G is mapped, the opcode load/store address range is 0 to 8G: @@ -330,9 +342,6 @@ memory_instantiate(WASMModuleInstance *module_inst, WASMModuleInstance *parent, * again here */ #endif /* end of OS_ENABLE_HW_BOUND_CHECK */ - if (memory_data_size > UINT32_MAX) - memory_data_size = (uint32)memory_data_size; - memory->module_type = Wasm_Module_Bytecode; memory->num_bytes_per_page = num_bytes_per_page; memory->cur_page_count = init_page_count; @@ -359,23 +368,9 @@ memory_instantiate(WASMModuleInstance *module_inst, WASMModuleInstance *parent, } } -#if WASM_ENABLE_FAST_JIT != 0 || WASM_ENABLE_JIT != 0 if (memory_data_size > 0) { -#if UINTPTR_MAX == UINT64_MAX - memory->mem_bound_check_1byte.u64 = memory_data_size - 1; - memory->mem_bound_check_2bytes.u64 = memory_data_size - 2; - memory->mem_bound_check_4bytes.u64 = memory_data_size - 4; - memory->mem_bound_check_8bytes.u64 = memory_data_size - 8; - memory->mem_bound_check_16bytes.u64 = memory_data_size - 16; -#else - memory->mem_bound_check_1byte.u32[0] = (uint32)memory_data_size - 1; - memory->mem_bound_check_2bytes.u32[0] = (uint32)memory_data_size - 2; - memory->mem_bound_check_4bytes.u32[0] = (uint32)memory_data_size - 4; - memory->mem_bound_check_8bytes.u32[0] = (uint32)memory_data_size - 8; - memory->mem_bound_check_16bytes.u32[0] = (uint32)memory_data_size - 16; -#endif + wasm_runtime_set_mem_bound_check_bytes(memory, memory_data_size); } -#endif #if WASM_ENABLE_SHARED_MEMORY != 0 if (is_shared_memory) { @@ -1779,6 +1774,10 @@ wasm_instantiate(WASMModule *module, WASMModuleInstance *parent, if (data_seg->is_passive) continue; #endif + if (is_sub_inst) + /* Ignore setting memory init data if the memory has been + initialized */ + continue; /* has check it in loader */ memory = module_inst->memories[data_seg->memory_index]; @@ -2472,15 +2471,20 @@ void wasm_module_free_internal(WASMModuleInstance *module_inst, WASMExecEnv *exec_env, uint32 ptr) { + WASMMemoryInstance *memory = wasm_get_default_memory(module_inst); + + if (!memory) { + return; + } + if (ptr) { - WASMMemoryInstance *memory = wasm_get_default_memory(module_inst); - uint8 *addr; + uint8 *addr = memory->memory_data + ptr; + uint8 *memory_data_end; - if (!memory) { - return; - } - - addr = memory->memory_data + ptr; + /* memory->memory_data_end may be changed in memory grow */ + SHARED_MEMORY_LOCK(memory); + memory_data_end = memory->memory_data_end; + SHARED_MEMORY_UNLOCK(memory); if (memory->heap_handle && memory->heap_data <= addr && addr < memory->heap_data_end) { @@ -2488,7 +2492,7 @@ wasm_module_free_internal(WASMModuleInstance *module_inst, } else if (module_inst->e->malloc_function && module_inst->e->free_function && memory->memory_data <= addr - && addr < memory->memory_data_end) { + && addr < memory_data_end) { execute_free_function(module_inst, exec_env, module_inst->e->free_function, ptr); } @@ -3150,7 +3154,9 @@ llvm_jit_memory_init(WASMModuleInstance *module_inst, uint32 seg_index, maddr = wasm_runtime_addr_app_to_native( (WASMModuleInstanceCommon *)module_inst, dst); + SHARED_MEMORY_LOCK(memory_inst); bh_memcpy_s(maddr, memory_inst->memory_data_size - dst, data + offset, len); + SHARED_MEMORY_UNLOCK(memory_inst); return true; }