mirror of
https://github.com/bytecodealliance/wasm-micro-runtime.git
synced 2024-11-26 15:32:05 +00:00
Enhance the native stack overflow check (#302)
This commit is contained in:
parent
9b8fc6ae95
commit
2fc7230009
|
@ -550,6 +550,8 @@ aot_lookup_function(const AOTModuleInstance *module_inst,
|
|||
|
||||
#ifdef OS_ENABLE_HW_BOUND_CHECK
|
||||
|
||||
#define STACK_OVERFLOW_CHECK_GUARD_PAGE_COUNT 3
|
||||
|
||||
static os_thread_local_attribute WASMExecEnv *aot_exec_env = NULL;
|
||||
|
||||
static inline uint8 *
|
||||
|
@ -567,6 +569,7 @@ aot_signal_handler(void *sig_addr)
|
|||
uint8 *mapped_mem_start_addr, *mapped_mem_end_addr;
|
||||
uint8 *stack_min_addr;
|
||||
uint32 page_size;
|
||||
uint32 guard_page_count = STACK_OVERFLOW_CHECK_GUARD_PAGE_COUNT;
|
||||
|
||||
/* Check whether current thread is running aot function */
|
||||
if (aot_exec_env
|
||||
|
@ -591,7 +594,8 @@ aot_signal_handler(void *sig_addr)
|
|||
os_longjmp(jmpbuf_node->jmpbuf, 1);
|
||||
}
|
||||
else if (stack_min_addr - page_size <= (uint8*)sig_addr
|
||||
&& (uint8*)sig_addr < stack_min_addr + page_size * 3) {
|
||||
&& (uint8*)sig_addr < stack_min_addr
|
||||
+ page_size * guard_page_count) {
|
||||
/* The address which causes segmentation fault is inside
|
||||
native thread's guard page */
|
||||
aot_set_exception_with_id(module_inst, EXCE_NATIVE_STACK_OVERFLOW);
|
||||
|
@ -621,11 +625,13 @@ touch_pages(uint8 *stack_min_addr, uint32 page_size)
|
|||
{
|
||||
uint8 sum = 0;
|
||||
while (1) {
|
||||
uint8 *touch_addr = os_alloca(page_size / 2);
|
||||
sum += *touch_addr;
|
||||
volatile uint8 *touch_addr =
|
||||
(volatile uint8*)os_alloca(page_size / 2);
|
||||
if (touch_addr < stack_min_addr + page_size) {
|
||||
sum += *(stack_min_addr + page_size - 1);
|
||||
break;
|
||||
}
|
||||
sum += *touch_addr;
|
||||
}
|
||||
return sum;
|
||||
}
|
||||
|
@ -640,9 +646,19 @@ invoke_native_with_hw_bound_check(WASMExecEnv *exec_env, void *func_ptr,
|
|||
WASMExecEnv **p_aot_exec_env = &aot_exec_env;
|
||||
WASMJmpBuf *jmpbuf_node, *jmpbuf_node_pop;
|
||||
uint32 page_size = os_getpagesize();
|
||||
uint32 guard_page_count = STACK_OVERFLOW_CHECK_GUARD_PAGE_COUNT;
|
||||
uint8 *stack_min_addr = get_stack_min_addr(exec_env, page_size);
|
||||
bool ret;
|
||||
|
||||
/* Check native stack overflow firstly to ensure we have enough
|
||||
native stack to run the following codes before actually calling
|
||||
the aot function in invokeNative function. */
|
||||
if ((uint8*)&module_inst < exec_env->native_stack_boundary
|
||||
+ page_size * (guard_page_count + 1)) {
|
||||
aot_set_exception_with_id(module_inst, EXCE_NATIVE_STACK_OVERFLOW);
|
||||
return false;
|
||||
}
|
||||
|
||||
if (aot_exec_env
|
||||
&& (aot_exec_env != exec_env)) {
|
||||
aot_set_exception(module_inst, "Invalid exec env.");
|
||||
|
@ -654,7 +670,8 @@ invoke_native_with_hw_bound_check(WASMExecEnv *exec_env, void *func_ptr,
|
|||
lazily grow the stack mapping as a guard page is hit. */
|
||||
touch_pages(stack_min_addr, page_size);
|
||||
/* First time to call aot function, protect one page */
|
||||
if (os_mprotect(stack_min_addr, page_size * 3, MMAP_PROT_NONE) != 0) {
|
||||
if (os_mprotect(stack_min_addr, page_size * guard_page_count,
|
||||
MMAP_PROT_NONE) != 0) {
|
||||
aot_set_exception(module_inst, "Set protected page failed.");
|
||||
return false;
|
||||
}
|
||||
|
@ -671,7 +688,7 @@ invoke_native_with_hw_bound_check(WASMExecEnv *exec_env, void *func_ptr,
|
|||
if (os_setjmp(jmpbuf_node->jmpbuf) == 0) {
|
||||
ret = wasm_runtime_invoke_native(exec_env, func_ptr, func_type,
|
||||
signature, attachment,
|
||||
argv, argc, argv);
|
||||
argv, argc, argv_ret);
|
||||
}
|
||||
else {
|
||||
/* Exception has been set in signal handler before calling longjmp */
|
||||
|
@ -683,7 +700,7 @@ invoke_native_with_hw_bound_check(WASMExecEnv *exec_env, void *func_ptr,
|
|||
wasm_runtime_free(jmpbuf_node);
|
||||
if (!exec_env->jmpbuf_stack_top) {
|
||||
/* Unprotect the guard page when the nested call depth is zero */
|
||||
os_mprotect(stack_min_addr, page_size * 3,
|
||||
os_mprotect(stack_min_addr, page_size * guard_page_count,
|
||||
MMAP_PROT_READ | MMAP_PROT_WRITE);
|
||||
*p_aot_exec_env = NULL;
|
||||
}
|
||||
|
@ -1113,6 +1130,19 @@ aot_invoke_native(WASMExecEnv *exec_env, uint32 func_idx,
|
|||
void *attachment;
|
||||
char buf[128];
|
||||
|
||||
#ifdef OS_ENABLE_HW_BOUND_CHECK
|
||||
uint32 page_size = os_getpagesize();
|
||||
uint32 guard_page_count = STACK_OVERFLOW_CHECK_GUARD_PAGE_COUNT;
|
||||
/* Check native stack overflow firstly to ensure we have enough
|
||||
native stack to run the following codes before actually calling
|
||||
the aot function in invokeNative function. */
|
||||
if ((uint8*)&module_inst < exec_env->native_stack_boundary
|
||||
+ page_size * (guard_page_count + 1)) {
|
||||
aot_set_exception_with_id(module_inst, EXCE_NATIVE_STACK_OVERFLOW);
|
||||
return false;
|
||||
}
|
||||
#endif
|
||||
|
||||
bh_assert(func_idx < aot_module->import_func_count);
|
||||
|
||||
import_func = aot_module->import_funcs + func_idx;
|
||||
|
|
|
@ -2797,6 +2797,10 @@ fail:
|
|||
return ret;
|
||||
}
|
||||
|
||||
#endif /* end of defined(BUILD_TARGET_X86_64) \
|
||||
|| defined(BUILD_TARGET_AMD_64) \
|
||||
|| defined(BUILD_TARGET_AARCH64) */
|
||||
|
||||
bool
|
||||
wasm_runtime_call_indirect(WASMExecEnv *exec_env,
|
||||
uint32_t element_indices,
|
||||
|
@ -2825,6 +2829,3 @@ wasm_runtime_call_indirect(WASMExecEnv *exec_env,
|
|||
return false;
|
||||
}
|
||||
|
||||
#endif /* end of defined(BUILD_TARGET_X86_64) \
|
||||
|| defined(BUILD_TARGET_AMD_64) \
|
||||
|| defined(BUILD_TARGET_AARCH64) */
|
||||
|
|
Loading…
Reference in New Issue
Block a user