Эх сурвалжийг харах

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.
Wenyong Huang 2 жил өмнө
parent
commit
4b1a6e5017

+ 48 - 37
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;
+    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
 #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;
+        /* 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
 #endif
-    bh_assert(total_size <= UINT32_MAX);
-
-#ifndef OS_ENABLE_HW_BOUND_CHECK
-    /* Allocate memory */
-    if (total_size > 0
-        && !(p = runtime_malloc(total_size, error_buf, error_buf_size))) {
-        return NULL;
+    {
+        /* 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
-    total_size = (total_size + page_size - 1) & ~(page_size - 1);
+#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;
 }
 

+ 72 - 30
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) {

+ 4 - 0
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);

+ 2 - 1
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, "::");
 

+ 8 - 0
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

+ 5 - 0
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");

+ 9 - 1
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

+ 44 - 38
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;
+    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 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;
+        /* 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
 #endif
-    bh_assert(memory_data_size <= 4 * (uint64)BH_GB);
-
-    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;
+    {
+        /* 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 /* 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)
 {
-    if (ptr) {
-        WASMMemoryInstance *memory = wasm_get_default_memory(module_inst);
-        uint8 *addr;
+    WASMMemoryInstance *memory = wasm_get_default_memory(module_inst);
 
-        if (!memory) {
-            return;
-        }
+    if (!memory) {
+        return;
+    }
+
+    if (ptr) {
+        uint8 *addr = memory->memory_data + ptr;
+        uint8 *memory_data_end;
 
-        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;
 }