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.
This commit is contained in:
Wenyong Huang
2023-10-30 11:07:01 +08:00
committed by GitHub
parent 51a6b069d2
commit 4b1a6e5017
8 changed files with 195 additions and 110 deletions

View File

@ -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;
}