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:
@@ -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) {
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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, "::");
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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");
|
||||
|
||||
Reference in New Issue
Block a user