@@ -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+
553555static os_thread_local_attribute WASMExecEnv * aot_exec_env = NULL ;
554556
555557static 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 ;
0 commit comments