mirror of
https://github.com/bytecodealliance/wasm-micro-runtime.git
synced 2025-05-09 13:16:26 +00:00
Fix app heap corrupted unchecked issue (#788)
Check whether app heap is corrupted in gc_migrate() and gci_dump(), and handle the failures in wasm/aot_enlarge_memory().
This commit is contained in:
parent
a121e45a1e
commit
3dff80157b
|
@ -1770,10 +1770,7 @@ aot_module_malloc(AOTModuleInstance *module_inst, uint32 size,
|
||||||
if (!addr) {
|
if (!addr) {
|
||||||
if (memory_inst->heap_handle.ptr
|
if (memory_inst->heap_handle.ptr
|
||||||
&& mem_allocator_is_heap_corrupted(memory_inst->heap_handle.ptr)) {
|
&& mem_allocator_is_heap_corrupted(memory_inst->heap_handle.ptr)) {
|
||||||
LOG_ERROR("Error: app heap is corrupted, if the wasm file "
|
wasm_runtime_show_app_heap_corrupted_prompt();
|
||||||
"is compiled by wasi-sdk-12.0 or larger version, "
|
|
||||||
"please add -Wl,--export=malloc -Wl,--export=free "
|
|
||||||
" to export malloc and free functions.");
|
|
||||||
aot_set_exception(module_inst, "app heap corrupted");
|
aot_set_exception(module_inst, "app heap corrupted");
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
|
@ -2014,6 +2011,7 @@ aot_enlarge_memory(AOTModuleInstance *module_inst, uint32 inc_page_count)
|
||||||
uint32 total_page_count, total_size_old, heap_size;
|
uint32 total_page_count, total_size_old, heap_size;
|
||||||
uint64 total_size;
|
uint64 total_size;
|
||||||
uint8 *memory_data_old, *heap_data_old, *memory_data, *heap_data;
|
uint8 *memory_data_old, *heap_data_old, *memory_data, *heap_data;
|
||||||
|
bool ret = true;
|
||||||
|
|
||||||
if (!memory_inst)
|
if (!memory_inst)
|
||||||
return false;
|
return false;
|
||||||
|
@ -2051,6 +2049,13 @@ aot_enlarge_memory(AOTModuleInstance *module_inst, uint32 inc_page_count)
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
if (heap_size > 0) {
|
||||||
|
if (mem_allocator_is_heap_corrupted(memory_inst->heap_handle.ptr)) {
|
||||||
|
wasm_runtime_show_app_heap_corrupted_prompt();
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (!(memory_data =
|
if (!(memory_data =
|
||||||
wasm_runtime_realloc(memory_data_old, (uint32)total_size))) {
|
wasm_runtime_realloc(memory_data_old, (uint32)total_size))) {
|
||||||
if (!(memory_data = wasm_runtime_malloc((uint32)total_size))) {
|
if (!(memory_data = wasm_runtime_malloc((uint32)total_size))) {
|
||||||
|
@ -2076,7 +2081,9 @@ aot_enlarge_memory(AOTModuleInstance *module_inst, uint32 inc_page_count)
|
||||||
(char *)heap_data_old
|
(char *)heap_data_old
|
||||||
+ (memory_data - memory_data_old),
|
+ (memory_data - memory_data_old),
|
||||||
heap_size)) {
|
heap_size)) {
|
||||||
return false;
|
/* Don't return here as memory->memory_data is obsolete and
|
||||||
|
must be updated to be correctly used later. */
|
||||||
|
ret = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2098,7 +2105,7 @@ aot_enlarge_memory(AOTModuleInstance *module_inst, uint32 inc_page_count)
|
||||||
memory_inst->mem_bound_check_8bytes.u32[0] = (uint32)total_size - 8;
|
memory_inst->mem_bound_check_8bytes.u32[0] = (uint32)total_size - 8;
|
||||||
memory_inst->mem_bound_check_16bytes.u32[0] = (uint32)total_size - 16;
|
memory_inst->mem_bound_check_16bytes.u32[0] = (uint32)total_size - 16;
|
||||||
}
|
}
|
||||||
return true;
|
return ret;
|
||||||
}
|
}
|
||||||
#else /* else of OS_ENABLE_HW_BOUND_CHECK */
|
#else /* else of OS_ENABLE_HW_BOUND_CHECK */
|
||||||
bool
|
bool
|
||||||
|
|
|
@ -4211,3 +4211,14 @@ fail:
|
||||||
wasm_runtime_free(results);
|
wasm_runtime_free(results);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
wasm_runtime_show_app_heap_corrupted_prompt()
|
||||||
|
{
|
||||||
|
LOG_ERROR("Error: app heap is corrupted, if the wasm file "
|
||||||
|
"is compiled by wasi-sdk-12.0 or higher version, "
|
||||||
|
"please add -Wl,--export=malloc -Wl,--export=free "
|
||||||
|
"to export malloc and free functions. If it is "
|
||||||
|
"compiled by asc, please add --exportRuntime to "
|
||||||
|
"export the runtime helpers.");
|
||||||
|
}
|
||||||
|
|
|
@ -839,6 +839,9 @@ wasm_runtime_invoke_c_api_native(WASMModuleInstanceCommon *module_inst,
|
||||||
uint32 argc, uint32 *argv, bool with_env,
|
uint32 argc, uint32 *argv, bool with_env,
|
||||||
void *wasm_c_api_env);
|
void *wasm_c_api_env);
|
||||||
|
|
||||||
|
void
|
||||||
|
wasm_runtime_show_app_heap_corrupted_prompt();
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -1826,10 +1826,7 @@ wasm_module_malloc(WASMModuleInstance *module_inst, uint32 size,
|
||||||
if (!addr) {
|
if (!addr) {
|
||||||
if (memory->heap_handle
|
if (memory->heap_handle
|
||||||
&& mem_allocator_is_heap_corrupted(memory->heap_handle)) {
|
&& mem_allocator_is_heap_corrupted(memory->heap_handle)) {
|
||||||
LOG_ERROR("Error: app heap is corrupted, if the wasm file "
|
wasm_runtime_show_app_heap_corrupted_prompt();
|
||||||
"is compiled by wasi-sdk-12.0 or larger version, "
|
|
||||||
"please add -Wl,--export=malloc -Wl,--export=free "
|
|
||||||
" to export malloc and free functions.");
|
|
||||||
wasm_set_exception(module_inst, "app heap corrupted");
|
wasm_set_exception(module_inst, "app heap corrupted");
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
|
@ -2057,6 +2054,7 @@ wasm_enlarge_memory(WASMModuleInstance *module, uint32 inc_page_count)
|
||||||
uint8 *new_memory_data, *memory_data, *heap_data_old;
|
uint8 *new_memory_data, *memory_data, *heap_data_old;
|
||||||
uint32 heap_size, total_size_old, total_page_count;
|
uint32 heap_size, total_size_old, total_page_count;
|
||||||
uint64 total_size;
|
uint64 total_size;
|
||||||
|
bool ret = true;
|
||||||
|
|
||||||
if (!memory)
|
if (!memory)
|
||||||
return false;
|
return false;
|
||||||
|
@ -2090,6 +2088,13 @@ wasm_enlarge_memory(WASMModuleInstance *module, uint32 inc_page_count)
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
if (heap_size > 0) {
|
||||||
|
if (mem_allocator_is_heap_corrupted(memory->heap_handle)) {
|
||||||
|
wasm_runtime_show_app_heap_corrupted_prompt();
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (!(new_memory_data =
|
if (!(new_memory_data =
|
||||||
wasm_runtime_realloc(memory_data, (uint32)total_size))) {
|
wasm_runtime_realloc(memory_data, (uint32)total_size))) {
|
||||||
if (!(new_memory_data = wasm_runtime_malloc((uint32)total_size))) {
|
if (!(new_memory_data = wasm_runtime_malloc((uint32)total_size))) {
|
||||||
|
@ -2111,7 +2116,9 @@ wasm_enlarge_memory(WASMModuleInstance *module, uint32 inc_page_count)
|
||||||
+ (new_memory_data - memory_data),
|
+ (new_memory_data - memory_data),
|
||||||
heap_size)
|
heap_size)
|
||||||
!= 0) {
|
!= 0) {
|
||||||
return false;
|
/* Don't return here as memory->memory_data is obsolete and
|
||||||
|
must be updated to be correctly used later. */
|
||||||
|
ret = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2122,7 +2129,7 @@ wasm_enlarge_memory(WASMModuleInstance *module, uint32 inc_page_count)
|
||||||
memory->memory_data_end =
|
memory->memory_data_end =
|
||||||
memory->memory_data + memory->num_bytes_per_page * total_page_count;
|
memory->memory_data + memory->num_bytes_per_page * total_page_count;
|
||||||
|
|
||||||
return true;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
#if WASM_ENABLE_REF_TYPES != 0
|
#if WASM_ENABLE_REF_TYPES != 0
|
||||||
|
|
|
@ -9,6 +9,12 @@
|
||||||
* around to avoid storing them in TLS.
|
* around to avoid storing them in TLS.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The defitions of type, macro and structure in this file should be
|
||||||
|
* consistent with those in wasi-libc:
|
||||||
|
* https://github.com/WebAssembly/wasi-libc/blob/main/libc-bottom-half/headers/public/wasi/api.h
|
||||||
|
*/
|
||||||
|
|
||||||
#ifndef WASMTIME_SSP_H
|
#ifndef WASMTIME_SSP_H
|
||||||
#define WASMTIME_SSP_H
|
#define WASMTIME_SSP_H
|
||||||
|
|
||||||
|
@ -201,8 +207,10 @@ typedef uint16_t __wasi_riflags_t;
|
||||||
|
|
||||||
typedef uint64_t __wasi_rights_t;
|
typedef uint64_t __wasi_rights_t;
|
||||||
|
|
||||||
// Observe that WASI defines rights in the plural form
|
/**
|
||||||
// TODO - re-factor to use RIGHTS instead of RIGHT
|
* Observe that WASI defines rights in the plural form
|
||||||
|
* TODO: refactor to use RIGHTS instead of RIGHT
|
||||||
|
*/
|
||||||
#define __WASI_RIGHT_FD_DATASYNC ((__wasi_rights_t)(1 << 0))
|
#define __WASI_RIGHT_FD_DATASYNC ((__wasi_rights_t)(1 << 0))
|
||||||
#define __WASI_RIGHT_FD_READ ((__wasi_rights_t)(1 << 1))
|
#define __WASI_RIGHT_FD_READ ((__wasi_rights_t)(1 << 1))
|
||||||
#define __WASI_RIGHT_FD_SEEK ((__wasi_rights_t)(1 << 2))
|
#define __WASI_RIGHT_FD_SEEK ((__wasi_rights_t)(1 << 2))
|
||||||
|
|
|
@ -759,7 +759,7 @@ gci_dump(gc_heap_t *heap)
|
||||||
else if (ut == HMU_FC)
|
else if (ut == HMU_FC)
|
||||||
inuse = 'F';
|
inuse = 'F';
|
||||||
|
|
||||||
if (size == 0) {
|
if (size == 0 || size > (uint8 *)end - (uint8 *)cur) {
|
||||||
os_printf("[GC_ERROR]Heap is corrupted, heap dump failed.\n");
|
os_printf("[GC_ERROR]Heap is corrupted, heap dump failed.\n");
|
||||||
heap->is_heap_corrupted = true;
|
heap->is_heap_corrupted = true;
|
||||||
return;
|
return;
|
||||||
|
@ -779,5 +779,8 @@ gci_dump(gc_heap_t *heap)
|
||||||
i++;
|
i++;
|
||||||
}
|
}
|
||||||
|
|
||||||
bh_assert(cur == end);
|
if (cur != end) {
|
||||||
|
os_printf("[GC_ERROR]Heap is corrupted, heap dump failed.\n");
|
||||||
|
heap->is_heap_corrupted = true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -183,6 +183,11 @@ gc_migrate(gc_handle_t handle, char *pool_buf_new, gc_size_t pool_buf_size)
|
||||||
if (offset == 0)
|
if (offset == 0)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
|
if (heap->is_heap_corrupted) {
|
||||||
|
os_printf("[GC_ERROR]Heap is corrupted, heap migrate failed.\n");
|
||||||
|
return GC_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
heap->base_addr = (uint8 *)base_addr_new;
|
heap->base_addr = (uint8 *)base_addr_new;
|
||||||
adjust_ptr((uint8 **)&heap->kfc_tree_root.left, offset);
|
adjust_ptr((uint8 **)&heap->kfc_tree_root.left, offset);
|
||||||
adjust_ptr((uint8 **)&heap->kfc_tree_root.right, offset);
|
adjust_ptr((uint8 **)&heap->kfc_tree_root.right, offset);
|
||||||
|
@ -193,7 +198,12 @@ gc_migrate(gc_handle_t handle, char *pool_buf_new, gc_size_t pool_buf_size)
|
||||||
|
|
||||||
while (cur < end) {
|
while (cur < end) {
|
||||||
size = hmu_get_size(cur);
|
size = hmu_get_size(cur);
|
||||||
bh_assert(size > 0);
|
|
||||||
|
if (size <= 0 || size > (uint8 *)end - (uint8 *)cur) {
|
||||||
|
os_printf("[GC_ERROR]Heap is corrupted, heap migrate failed.\n");
|
||||||
|
heap->is_heap_corrupted = true;
|
||||||
|
return GC_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
if (hmu_get_ut(cur) == HMU_FC && !HMU_IS_FC_NORMAL(size)) {
|
if (hmu_get_ut(cur) == HMU_FC && !HMU_IS_FC_NORMAL(size)) {
|
||||||
tree_node = (hmu_tree_node_t *)cur;
|
tree_node = (hmu_tree_node_t *)cur;
|
||||||
|
@ -207,7 +217,12 @@ gc_migrate(gc_handle_t handle, char *pool_buf_new, gc_size_t pool_buf_size)
|
||||||
cur = (hmu_t *)((char *)cur + size);
|
cur = (hmu_t *)((char *)cur + size);
|
||||||
}
|
}
|
||||||
|
|
||||||
bh_assert(cur == end);
|
if (cur != end) {
|
||||||
|
os_printf("[GC_ERROR]Heap is corrupted, heap migrate failed.\n");
|
||||||
|
heap->is_heap_corrupted = true;
|
||||||
|
return GC_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue
Block a user