Skip to content

Commit 2fc7230

Browse files
authored
Enhance the native stack overflow check (#302)
1 parent 9b8fc6a commit 2fc7230

File tree

2 files changed

+40
-9
lines changed

2 files changed

+40
-9
lines changed

core/iwasm/aot/aot_runtime.c

Lines changed: 36 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -550,6 +550,8 @@ aot_lookup_function(const AOTModuleInstance *module_inst,
550550

551551
#ifdef OS_ENABLE_HW_BOUND_CHECK
552552

553+
#define STACK_OVERFLOW_CHECK_GUARD_PAGE_COUNT 3
554+
553555
static os_thread_local_attribute WASMExecEnv *aot_exec_env = NULL;
554556

555557
static inline uint8 *
@@ -567,6 +569,7 @@ aot_signal_handler(void *sig_addr)
567569
uint8 *mapped_mem_start_addr, *mapped_mem_end_addr;
568570
uint8 *stack_min_addr;
569571
uint32 page_size;
572+
uint32 guard_page_count = STACK_OVERFLOW_CHECK_GUARD_PAGE_COUNT;
570573

571574
/* Check whether current thread is running aot function */
572575
if (aot_exec_env
@@ -591,7 +594,8 @@ aot_signal_handler(void *sig_addr)
591594
os_longjmp(jmpbuf_node->jmpbuf, 1);
592595
}
593596
else if (stack_min_addr - page_size <= (uint8*)sig_addr
594-
&& (uint8*)sig_addr < stack_min_addr + page_size * 3) {
597+
&& (uint8*)sig_addr < stack_min_addr
598+
+ page_size * guard_page_count) {
595599
/* The address which causes segmentation fault is inside
596600
native thread's guard page */
597601
aot_set_exception_with_id(module_inst, EXCE_NATIVE_STACK_OVERFLOW);
@@ -621,11 +625,13 @@ touch_pages(uint8 *stack_min_addr, uint32 page_size)
621625
{
622626
uint8 sum = 0;
623627
while (1) {
624-
uint8 *touch_addr = os_alloca(page_size / 2);
625-
sum += *touch_addr;
628+
volatile uint8 *touch_addr =
629+
(volatile uint8*)os_alloca(page_size / 2);
626630
if (touch_addr < stack_min_addr + page_size) {
631+
sum += *(stack_min_addr + page_size - 1);
627632
break;
628633
}
634+
sum += *touch_addr;
629635
}
630636
return sum;
631637
}
@@ -640,9 +646,19 @@ invoke_native_with_hw_bound_check(WASMExecEnv *exec_env, void *func_ptr,
640646
WASMExecEnv **p_aot_exec_env = &aot_exec_env;
641647
WASMJmpBuf *jmpbuf_node, *jmpbuf_node_pop;
642648
uint32 page_size = os_getpagesize();
649+
uint32 guard_page_count = STACK_OVERFLOW_CHECK_GUARD_PAGE_COUNT;
643650
uint8 *stack_min_addr = get_stack_min_addr(exec_env, page_size);
644651
bool ret;
645652

653+
/* Check native stack overflow firstly to ensure we have enough
654+
native stack to run the following codes before actually calling
655+
the aot function in invokeNative function. */
656+
if ((uint8*)&module_inst < exec_env->native_stack_boundary
657+
+ page_size * (guard_page_count + 1)) {
658+
aot_set_exception_with_id(module_inst, EXCE_NATIVE_STACK_OVERFLOW);
659+
return false;
660+
}
661+
646662
if (aot_exec_env
647663
&& (aot_exec_env != exec_env)) {
648664
aot_set_exception(module_inst, "Invalid exec env.");
@@ -654,7 +670,8 @@ invoke_native_with_hw_bound_check(WASMExecEnv *exec_env, void *func_ptr,
654670
lazily grow the stack mapping as a guard page is hit. */
655671
touch_pages(stack_min_addr, page_size);
656672
/* First time to call aot function, protect one page */
657-
if (os_mprotect(stack_min_addr, page_size * 3, MMAP_PROT_NONE) != 0) {
673+
if (os_mprotect(stack_min_addr, page_size * guard_page_count,
674+
MMAP_PROT_NONE) != 0) {
658675
aot_set_exception(module_inst, "Set protected page failed.");
659676
return false;
660677
}
@@ -671,7 +688,7 @@ invoke_native_with_hw_bound_check(WASMExecEnv *exec_env, void *func_ptr,
671688
if (os_setjmp(jmpbuf_node->jmpbuf) == 0) {
672689
ret = wasm_runtime_invoke_native(exec_env, func_ptr, func_type,
673690
signature, attachment,
674-
argv, argc, argv);
691+
argv, argc, argv_ret);
675692
}
676693
else {
677694
/* 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,
683700
wasm_runtime_free(jmpbuf_node);
684701
if (!exec_env->jmpbuf_stack_top) {
685702
/* Unprotect the guard page when the nested call depth is zero */
686-
os_mprotect(stack_min_addr, page_size * 3,
703+
os_mprotect(stack_min_addr, page_size * guard_page_count,
687704
MMAP_PROT_READ | MMAP_PROT_WRITE);
688705
*p_aot_exec_env = NULL;
689706
}
@@ -1113,6 +1130,19 @@ aot_invoke_native(WASMExecEnv *exec_env, uint32 func_idx,
11131130
void *attachment;
11141131
char buf[128];
11151132

1133+
#ifdef OS_ENABLE_HW_BOUND_CHECK
1134+
uint32 page_size = os_getpagesize();
1135+
uint32 guard_page_count = STACK_OVERFLOW_CHECK_GUARD_PAGE_COUNT;
1136+
/* Check native stack overflow firstly to ensure we have enough
1137+
native stack to run the following codes before actually calling
1138+
the aot function in invokeNative function. */
1139+
if ((uint8*)&module_inst < exec_env->native_stack_boundary
1140+
+ page_size * (guard_page_count + 1)) {
1141+
aot_set_exception_with_id(module_inst, EXCE_NATIVE_STACK_OVERFLOW);
1142+
return false;
1143+
}
1144+
#endif
1145+
11161146
bh_assert(func_idx < aot_module->import_func_count);
11171147

11181148
import_func = aot_module->import_funcs + func_idx;

core/iwasm/common/wasm_runtime_common.c

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2797,6 +2797,10 @@ wasm_runtime_invoke_native(WASMExecEnv *exec_env, void *func_ptr,
27972797
return ret;
27982798
}
27992799

2800+
#endif /* end of defined(BUILD_TARGET_X86_64) \
2801+
|| defined(BUILD_TARGET_AMD_64) \
2802+
|| defined(BUILD_TARGET_AARCH64) */
2803+
28002804
bool
28012805
wasm_runtime_call_indirect(WASMExecEnv *exec_env,
28022806
uint32_t element_indices,
@@ -2825,6 +2829,3 @@ wasm_runtime_call_indirect(WASMExecEnv *exec_env,
28252829
return false;
28262830
}
28272831

2828-
#endif /* end of defined(BUILD_TARGET_X86_64) \
2829-
|| defined(BUILD_TARGET_AMD_64) \
2830-
|| defined(BUILD_TARGET_AARCH64) */

0 commit comments

Comments
 (0)