Ver Fonte

Add wasm_runtime_detect_native_stack_overflow_size (#3355)

- Add a few API (https://github.com/bytecodealliance/wasm-micro-runtime/issues/3325)
   ```c
   wasm_runtime_detect_native_stack_overflow_size
   wasm_runtime_detect_native_stack_overflow
   ```
- Adapt the runtime to use them
- Adapt samples/native-stack-overflow to use them
- Add a few missing overflow checks in the interpreters
- Build and run the sample on the CI
YAMAMOTO Takashi há 1 ano atrás
pai
commit
410ee580ae

+ 7 - 0
.github/workflows/compilation_on_android_ubuntu.yml

@@ -491,6 +491,13 @@ jobs:
           ./iwasm wasm-apps/trap.aot | grep "#" > call_stack_aot.txt
           ./iwasm wasm-apps/trap.aot | grep "#" > call_stack_aot.txt
           bash -x ../symbolicate.sh
           bash -x ../symbolicate.sh
 
 
+      - name: Build Sample [native-stack-overflow]
+        run: |
+          cd samples/native-stack-overflow
+          ./build.sh
+          ./run.sh test1
+          ./run.sh test2
+
   test:
   test:
     needs:
     needs:
       [
       [

+ 9 - 0
.github/workflows/compilation_on_macos.yml

@@ -379,3 +379,12 @@ jobs:
           ./iwasm wasm-apps/trap.wasm | grep "#" > call_stack.txt
           ./iwasm wasm-apps/trap.wasm | grep "#" > call_stack.txt
           ./iwasm wasm-apps/trap.aot | grep "#" > call_stack_aot.txt
           ./iwasm wasm-apps/trap.aot | grep "#" > call_stack_aot.txt
           bash -x ../symbolicate.sh
           bash -x ../symbolicate.sh
+
+      # skip on arm64 (macos-14) for now
+      - name: Build Sample [native-stack-overflow]
+        if: matrix.os != 'macos-14'
+        run: |
+          cd samples/native-stack-overflow
+          ./build.sh
+          ./run.sh test1
+          ./run.sh test2

+ 8 - 0
.github/workflows/nightly_run.yml

@@ -548,6 +548,13 @@ jobs:
           ./build.sh
           ./build.sh
           ./run.sh
           ./run.sh
 
 
+      - name: Build Sample [native-stack-overflow]
+        run: |
+          cd samples/native-stack-overflow
+          ./build.sh
+          ./run.sh test1
+          ./run.sh test2
+
       - name: Build Sample [native-lib]
       - name: Build Sample [native-lib]
         run: |
         run: |
           mkdir build && cd build
           mkdir build && cd build
@@ -567,6 +574,7 @@ jobs:
           python3 ./sample_test_run.py $(pwd)/out
           python3 ./sample_test_run.py $(pwd)/out
           exit $?
           exit $?
         working-directory: ./wamr-app-framework/samples/simple
         working-directory: ./wamr-app-framework/samples/simple
+
   test:
   test:
     needs:
     needs:
       [
       [

+ 2 - 9
core/iwasm/aot/aot_runtime.c

@@ -1967,8 +1967,6 @@ invoke_native_with_hw_bound_check(WASMExecEnv *exec_env, void *func_ptr,
     AOTModuleInstance *module_inst = (AOTModuleInstance *)exec_env->module_inst;
     AOTModuleInstance *module_inst = (AOTModuleInstance *)exec_env->module_inst;
     WASMExecEnv *exec_env_tls = wasm_runtime_get_exec_env_tls();
     WASMExecEnv *exec_env_tls = wasm_runtime_get_exec_env_tls();
     WASMJmpBuf jmpbuf_node = { 0 }, *jmpbuf_node_pop;
     WASMJmpBuf jmpbuf_node = { 0 }, *jmpbuf_node_pop;
-    uint32 page_size = os_getpagesize();
-    uint32 guard_page_count = STACK_OVERFLOW_CHECK_GUARD_PAGE_COUNT;
 #ifdef BH_PLATFORM_WINDOWS
 #ifdef BH_PLATFORM_WINDOWS
     int result;
     int result;
     bool has_exception;
     bool has_exception;
@@ -1979,10 +1977,7 @@ invoke_native_with_hw_bound_check(WASMExecEnv *exec_env, void *func_ptr,
     /* Check native stack overflow firstly to ensure we have enough
     /* Check native stack overflow firstly to ensure we have enough
        native stack to run the following codes before actually calling
        native stack to run the following codes before actually calling
        the aot function in invokeNative function. */
        the aot function in invokeNative function. */
-    RECORD_STACK_USAGE(exec_env, (uint8 *)&module_inst);
-    if ((uint8 *)&module_inst
-        < exec_env->native_stack_boundary + page_size * guard_page_count) {
-        aot_set_exception_with_id(module_inst, EXCE_NATIVE_STACK_OVERFLOW);
+    if (!wasm_runtime_detect_native_stack_overflow(exec_env)) {
         return false;
         return false;
     }
     }
 
 
@@ -2790,9 +2785,7 @@ aot_call_indirect(WASMExecEnv *exec_env, uint32 tbl_idx, uint32 table_elem_idx,
        exec_env->native_stack_boundary must have been set, we don't set
        exec_env->native_stack_boundary must have been set, we don't set
        it again */
        it again */
 
 
-    RECORD_STACK_USAGE(exec_env, (uint8 *)&module_inst);
-    if ((uint8 *)&module_inst < exec_env->native_stack_boundary) {
-        aot_set_exception_with_id(module_inst, EXCE_NATIVE_STACK_OVERFLOW);
+    if (!wasm_runtime_detect_native_stack_overflow(exec_env)) {
         goto fail;
         goto fail;
     }
     }
 
 

+ 56 - 0
core/iwasm/common/wasm_runtime_common.c

@@ -7015,3 +7015,59 @@ wasm_runtime_get_module_name(wasm_module_t module)
 
 
     return "";
     return "";
 }
 }
+
+/*
+ * wasm_runtime_detect_native_stack_overflow
+ *
+ * - raise "native stack overflow" exception if available native stack
+ *   at this point is less than WASM_STACK_GUARD_SIZE. in that case,
+ *   return false.
+ *
+ * - update native_stack_top_min.
+ */
+bool
+wasm_runtime_detect_native_stack_overflow(WASMExecEnv *exec_env)
+{
+    uint8 *boundary = exec_env->native_stack_boundary;
+    RECORD_STACK_USAGE(exec_env, (uint8 *)&boundary);
+    if (boundary == NULL) {
+        /* the platfrom doesn't support os_thread_get_stack_boundary */
+        return true;
+    }
+#if defined(OS_ENABLE_HW_BOUND_CHECK) && WASM_DISABLE_STACK_HW_BOUND_CHECK == 0
+    uint32 page_size = os_getpagesize();
+    uint32 guard_page_count = STACK_OVERFLOW_CHECK_GUARD_PAGE_COUNT;
+    boundary = boundary + page_size * guard_page_count;
+#endif
+    if ((uint8 *)&boundary < boundary) {
+        wasm_runtime_set_exception(wasm_runtime_get_module_inst(exec_env),
+                                   "native stack overflow");
+        return false;
+    }
+    return true;
+}
+
+bool
+wasm_runtime_detect_native_stack_overflow_size(WASMExecEnv *exec_env,
+                                               uint32 requested_size)
+{
+    uint8 *boundary = exec_env->native_stack_boundary;
+    RECORD_STACK_USAGE(exec_env, (uint8 *)&boundary);
+    if (boundary == NULL) {
+        /* the platfrom doesn't support os_thread_get_stack_boundary */
+        return true;
+    }
+#if defined(OS_ENABLE_HW_BOUND_CHECK) && WASM_DISABLE_STACK_HW_BOUND_CHECK == 0
+    uint32 page_size = os_getpagesize();
+    uint32 guard_page_count = STACK_OVERFLOW_CHECK_GUARD_PAGE_COUNT;
+    boundary = boundary + page_size * guard_page_count;
+#endif
+    /* adjust the boundary for the requested size */
+    boundary = boundary - WASM_STACK_GUARD_SIZE + requested_size;
+    if ((uint8 *)&boundary < boundary) {
+        wasm_runtime_set_exception(wasm_runtime_get_module_inst(exec_env),
+                                   "native stack overflow");
+        return false;
+    }
+    return true;
+}

+ 7 - 0
core/iwasm/common/wasm_runtime_common.h

@@ -1189,6 +1189,13 @@ wasm_runtime_end_blocking_op(WASMExecEnv *exec_env);
 void
 void
 wasm_runtime_interrupt_blocking_op(WASMExecEnv *exec_env);
 wasm_runtime_interrupt_blocking_op(WASMExecEnv *exec_env);
 
 
+WASM_RUNTIME_API_EXTERN bool
+wasm_runtime_detect_native_stack_overflow(WASMExecEnv *exec_env);
+
+WASM_RUNTIME_API_EXTERN bool
+wasm_runtime_detect_native_stack_overflow_size(WASMExecEnv *exec_env,
+                                               uint32 requested_size);
+
 #if WASM_ENABLE_LINUX_PERF != 0
 #if WASM_ENABLE_LINUX_PERF != 0
 bool
 bool
 wasm_runtime_get_linux_perf(void);
 wasm_runtime_get_linux_perf(void);

+ 51 - 0
core/iwasm/include/wasm_export.h

@@ -1756,6 +1756,57 @@ wasm_runtime_set_module_name(wasm_module_t module, const char *name,
 WASM_RUNTIME_API_EXTERN const char *
 WASM_RUNTIME_API_EXTERN const char *
 wasm_runtime_get_module_name(wasm_module_t module);
 wasm_runtime_get_module_name(wasm_module_t module);
 
 
+/*
+ * wasm_runtime_detect_native_stack_overflow
+ *
+ * Detect native stack shortage.
+ * Ensure that the calling thread still has a reasonable amount of
+ * native stack (WASM_STACK_GUARD_SIZE bytes) available.
+ *
+ * If enough stack is left, this function returns true.
+ * Otherwise, this function raises a "native stack overflow" trap and
+ * returns false.
+ *
+ * Note: please do not expect a very strict detection. it's a good idea
+ * to give some margins. wasm_runtime_detect_native_stack_overflow itself
+ * requires a small amount of stack to run.
+ */
+WASM_RUNTIME_API_EXTERN bool
+wasm_runtime_detect_native_stack_overflow(wasm_exec_env_t exec_env);
+
+/*
+ * wasm_runtime_detect_native_stack_overflow_size
+ *
+ * Similar to wasm_runtime_detect_native_stack_overflow,
+ * but use the caller-specified size instead of WASM_STACK_GUARD_SIZE.
+ *
+ * An expected usage:
+ * ```c
+ * __attribute__((noinline))  // inlining can break the stack check
+ * void stack_hog(void)
+ * {
+ *     // consume a lot of stack here
+ * }
+ *
+ * void
+ * stack_hog_wrapper(exec_env) {
+ *     // the amount of stack stack_hog would consume,
+ *     // plus a small margin
+ *     uint32_t size = 10000000;
+ *
+ *     if (!wasm_runtime_detect_native_stack_overflow_size(exec_env, size)) {
+ *         // wasm_runtime_detect_native_stack_overflow_size has raised
+ *         // a trap.
+ *         return;
+ *     }
+ *     stack_hog();
+ * }
+ * ```
+ */
+WASM_RUNTIME_API_EXTERN bool
+wasm_runtime_detect_native_stack_overflow_size(wasm_exec_env_t exec_env,
+                                               uint32_t required_size);
+
 #ifdef __cplusplus
 #ifdef __cplusplus
 }
 }
 #endif
 #endif

+ 19 - 6
core/iwasm/interpreter/wasm_interp_classic.c

@@ -1159,6 +1159,10 @@ wasm_interp_call_func_native(WASMModuleInstance *module_inst,
     uint8 *frame_ref;
     uint8 *frame_ref;
 #endif
 #endif
 
 
+    if (!wasm_runtime_detect_native_stack_overflow(exec_env)) {
+        return;
+    }
+
     all_cell_num = local_cell_num;
     all_cell_num = local_cell_num;
 #if WASM_ENABLE_GC != 0
 #if WASM_ENABLE_GC != 0
     all_cell_num += (local_cell_num + 3) / 4;
     all_cell_num += (local_cell_num + 3) / 4;
@@ -1290,6 +1294,14 @@ wasm_interp_call_func_import(WASMModuleInstance *module_inst,
     uintptr_t aux_stack_origin_boundary = 0;
     uintptr_t aux_stack_origin_boundary = 0;
     uintptr_t aux_stack_origin_bottom = 0;
     uintptr_t aux_stack_origin_bottom = 0;
 
 
+    /*
+     * perform stack overflow check before calling
+     * wasm_interp_call_func_bytecode recursively.
+     */
+    if (!wasm_runtime_detect_native_stack_overflow(exec_env)) {
+        return;
+    }
+
     if (!sub_func_inst) {
     if (!sub_func_inst) {
         snprintf(buf, sizeof(buf),
         snprintf(buf, sizeof(buf),
                  "failed to call unlinked import function (%s, %s)",
                  "failed to call unlinked import function (%s, %s)",
@@ -7108,12 +7120,13 @@ wasm_interp_call_wasm(WASMModuleInstance *module_inst, WASMExecEnv *exec_env,
     }
     }
     argc = function->param_cell_num;
     argc = function->param_cell_num;
 
 
-    RECORD_STACK_USAGE(exec_env, (uint8 *)&prev_frame);
-#if !(defined(OS_ENABLE_HW_BOUND_CHECK) \
-      && WASM_DISABLE_STACK_HW_BOUND_CHECK == 0)
-    if ((uint8 *)&prev_frame < exec_env->native_stack_boundary) {
-        wasm_set_exception((WASMModuleInstance *)exec_env->module_inst,
-                           "native stack overflow");
+#if defined(OS_ENABLE_HW_BOUND_CHECK) && WASM_DISABLE_STACK_HW_BOUND_CHECK == 0
+    /*
+     * wasm_runtime_detect_native_stack_overflow is done by
+     * call_wasm_with_hw_bound_check.
+     */
+#else
+    if (!wasm_runtime_detect_native_stack_overflow(exec_env)) {
         return;
         return;
     }
     }
 #endif
 #endif

+ 19 - 6
core/iwasm/interpreter/wasm_interp_fast.c

@@ -1167,6 +1167,10 @@ wasm_interp_call_func_native(WASMModuleInstance *module_inst,
     all_cell_num += (local_cell_num + 3) / 4;
     all_cell_num += (local_cell_num + 3) / 4;
 #endif
 #endif
 
 
+    if (!wasm_runtime_detect_native_stack_overflow(exec_env)) {
+        return;
+    }
+
     if (!(frame =
     if (!(frame =
               ALLOC_FRAME(exec_env, wasm_interp_interp_frame_size(all_cell_num),
               ALLOC_FRAME(exec_env, wasm_interp_interp_frame_size(all_cell_num),
                           prev_frame)))
                           prev_frame)))
@@ -1275,6 +1279,14 @@ wasm_interp_call_func_import(WASMModuleInstance *module_inst,
     uintptr_t aux_stack_origin_boundary = 0;
     uintptr_t aux_stack_origin_boundary = 0;
     uintptr_t aux_stack_origin_bottom = 0;
     uintptr_t aux_stack_origin_bottom = 0;
 
 
+    /*
+     * perform stack overflow check before calling
+     * wasm_interp_call_func_bytecode recursively.
+     */
+    if (!wasm_runtime_detect_native_stack_overflow(exec_env)) {
+        return;
+    }
+
     if (!sub_func_inst) {
     if (!sub_func_inst) {
         snprintf(buf, sizeof(buf),
         snprintf(buf, sizeof(buf),
                  "failed to call unlinked import function (%s, %s)",
                  "failed to call unlinked import function (%s, %s)",
@@ -6081,12 +6093,13 @@ wasm_interp_call_wasm(WASMModuleInstance *module_inst, WASMExecEnv *exec_env,
     }
     }
     argc = function->param_cell_num;
     argc = function->param_cell_num;
 
 
-    RECORD_STACK_USAGE(exec_env, (uint8 *)&prev_frame);
-#if !(defined(OS_ENABLE_HW_BOUND_CHECK) \
-      && WASM_DISABLE_STACK_HW_BOUND_CHECK == 0)
-    if ((uint8 *)&prev_frame < exec_env->native_stack_boundary) {
-        wasm_set_exception((WASMModuleInstance *)exec_env->module_inst,
-                           "native stack overflow");
+#if defined(OS_ENABLE_HW_BOUND_CHECK) && WASM_DISABLE_STACK_HW_BOUND_CHECK == 0
+    /*
+     * wasm_runtime_detect_native_stack_overflow is done by
+     * call_wasm_with_hw_bound_check.
+     */
+#else
+    if (!wasm_runtime_detect_native_stack_overflow(exec_env)) {
         return;
         return;
     }
     }
 #endif
 #endif

+ 1 - 6
core/iwasm/interpreter/wasm_runtime.c

@@ -3139,8 +3139,6 @@ call_wasm_with_hw_bound_check(WASMModuleInstance *module_inst,
 {
 {
     WASMExecEnv *exec_env_tls = wasm_runtime_get_exec_env_tls();
     WASMExecEnv *exec_env_tls = wasm_runtime_get_exec_env_tls();
     WASMJmpBuf jmpbuf_node = { 0 }, *jmpbuf_node_pop;
     WASMJmpBuf jmpbuf_node = { 0 }, *jmpbuf_node_pop;
-    uint32 page_size = os_getpagesize();
-    uint32 guard_page_count = STACK_OVERFLOW_CHECK_GUARD_PAGE_COUNT;
     WASMRuntimeFrame *prev_frame = wasm_exec_env_get_cur_frame(exec_env);
     WASMRuntimeFrame *prev_frame = wasm_exec_env_get_cur_frame(exec_env);
     uint8 *prev_top = exec_env->wasm_stack.top;
     uint8 *prev_top = exec_env->wasm_stack.top;
 #ifdef BH_PLATFORM_WINDOWS
 #ifdef BH_PLATFORM_WINDOWS
@@ -3153,10 +3151,7 @@ call_wasm_with_hw_bound_check(WASMModuleInstance *module_inst,
     /* Check native stack overflow firstly to ensure we have enough
     /* Check native stack overflow firstly to ensure we have enough
        native stack to run the following codes before actually calling
        native stack to run the following codes before actually calling
        the aot function in invokeNative function. */
        the aot function in invokeNative function. */
-    RECORD_STACK_USAGE(exec_env, (uint8 *)&exec_env_tls);
-    if ((uint8 *)&exec_env_tls
-        < exec_env->native_stack_boundary + page_size * guard_page_count) {
-        wasm_set_exception(module_inst, "native stack overflow");
+    if (!wasm_runtime_detect_native_stack_overflow(exec_env)) {
         return;
         return;
     }
     }
 
 

+ 5 - 0
samples/native-stack-overflow/CMakeLists.txt

@@ -72,6 +72,11 @@ if (CMAKE_C_COMPILER_ID MATCHES "Clang" AND CMAKE_C_COMPILER_VERSION VERSION_GRE
 set (CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fstack-usage")
 set (CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fstack-usage")
 endif ()
 endif ()
 
 
+# GCC doesn't have disable_tail_calls attribute
+if (CMAKE_C_COMPILER_ID MATCHES "GNU")
+set (CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fno-optimize-sibling-calls")
+endif ()
+
 # build out vmlib
 # build out vmlib
 set (WAMR_ROOT_DIR ${CMAKE_CURRENT_LIST_DIR}/../..)
 set (WAMR_ROOT_DIR ${CMAKE_CURRENT_LIST_DIR}/../..)
 include (${WAMR_ROOT_DIR}/build-scripts/runtime_lib.cmake)
 include (${WAMR_ROOT_DIR}/build-scripts/runtime_lib.cmake)

+ 2 - 2
samples/native-stack-overflow/build.sh

@@ -69,7 +69,7 @@ echo "#################### build wasm apps done"
 
 
 echo "#################### aot-compile"
 echo "#################### aot-compile"
 WAMRC=${WAMR_DIR}/wamr-compiler/build/wamrc
 WAMRC=${WAMR_DIR}/wamr-compiler/build/wamrc
-${WAMRC} -o ${OUT_DIR}/wasm-apps/${OUT_FILE}.aot ${OUT_DIR}/wasm-apps/${OUT_FILE}
+${WAMRC} -o ${OUT_DIR}/wasm-apps/${OUT_FILE}.aot --size-level=0 ${OUT_DIR}/wasm-apps/${OUT_FILE}
 
 
 echo "#################### aot-compile (--bounds-checks=1)"
 echo "#################### aot-compile (--bounds-checks=1)"
-${WAMRC} -o ${OUT_DIR}/wasm-apps/${OUT_FILE}.aot.bounds-checks --bounds-checks=1 ${OUT_DIR}/wasm-apps/${OUT_FILE}
+${WAMRC} -o ${OUT_DIR}/wasm-apps/${OUT_FILE}.aot.bounds-checks --size-level=0 --bounds-checks=1 ${OUT_DIR}/wasm-apps/${OUT_FILE}

+ 1 - 1
samples/native-stack-overflow/src/main.c

@@ -114,7 +114,7 @@ main(int argc, char **argv)
            "--------\n");
            "--------\n");
 
 
     unsigned int stack;
     unsigned int stack;
-    unsigned int prevstack;
+    unsigned int prevstack = 0; /* appease GCC -Wmaybe-uninitialized */
     unsigned int stack_range_start = 0;
     unsigned int stack_range_start = 0;
     unsigned int stack_range_end = 4096 * 6;
     unsigned int stack_range_end = 4096 * 6;
     unsigned int step = 16;
     unsigned int step = 16;

+ 14 - 23
samples/native-stack-overflow/src/native_impl.c

@@ -9,10 +9,6 @@
 #include <stdio.h>
 #include <stdio.h>
 #include <string.h>
 #include <string.h>
 
 
-#if defined(__APPLE__)
-#include <Availability.h>
-#endif
-
 #include "wasm_export.h"
 #include "wasm_export.h"
 #include "bh_platform.h"
 #include "bh_platform.h"
 
 
@@ -45,9 +41,12 @@ host_consume_stack_and_call_indirect(wasm_exec_env_t exec_env, uint32_t funcidx,
     void *boundary = os_thread_get_stack_boundary();
     void *boundary = os_thread_get_stack_boundary();
     void *fp = __builtin_frame_address(0);
     void *fp = __builtin_frame_address(0);
     ptrdiff_t diff = fp - boundary;
     ptrdiff_t diff = fp - boundary;
-    if ((unsigned char *)fp < (unsigned char *)boundary + 1024 * 5) {
-        wasm_runtime_set_exception(wasm_runtime_get_module_inst(exec_env),
-                                   "native stack overflow 2");
+    /*
+     * because this function performs recursive calls depending on
+     * the user input, we don't have an apriori knowledge how much stack
+     * we need. perform the overflow check on each iteration.
+     */
+    if (!wasm_runtime_detect_native_stack_overflow(exec_env)) {
         return 0;
         return 0;
     }
     }
     if (diff > stack) {
     if (diff > stack) {
@@ -63,27 +62,13 @@ host_consume_stack_and_call_indirect(wasm_exec_env_t exec_env, uint32_t funcidx,
 
 
 __attribute__((noinline)) static uint32_t
 __attribute__((noinline)) static uint32_t
 consume_stack1(wasm_exec_env_t exec_env, void *base, uint32_t stack)
 consume_stack1(wasm_exec_env_t exec_env, void *base, uint32_t stack)
+#if defined(__clang__)
     __attribute__((disable_tail_calls))
     __attribute__((disable_tail_calls))
+#endif
 {
 {
     void *fp = __builtin_frame_address(0);
     void *fp = __builtin_frame_address(0);
     ptrdiff_t diff = (unsigned char *)base - (unsigned char *)fp;
     ptrdiff_t diff = (unsigned char *)base - (unsigned char *)fp;
     assert(diff > 0);
     assert(diff > 0);
-    char buf[16];
-    /*
-     * note: we prefer to use memset_s here because, unlike memset,
-     * memset_s is not allowed to be optimized away.
-     *
-     * memset_s is available for macOS 10.13+ according to:
-     * https://developer.apple.com/documentation/kernel/2876438-memset_s
-     */
-#if defined(__STDC_LIB_EXT1__)                  \
-    || (defined(__MAC_OS_X_VERSION_MAX_ALLOWED) \
-        && __MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_3)
-    memset_s(buf, sizeof(buf), 0, sizeof(buf));
-#else
-#warning memset_s is not available
-    memset(buf, 0, sizeof(buf));
-#endif
     if (diff > stack) {
     if (diff > stack) {
         return diff;
         return diff;
     }
     }
@@ -93,6 +78,12 @@ consume_stack1(wasm_exec_env_t exec_env, void *base, uint32_t stack)
 uint32_t
 uint32_t
 host_consume_stack(wasm_exec_env_t exec_env, uint32_t stack)
 host_consume_stack(wasm_exec_env_t exec_env, uint32_t stack)
 {
 {
+    /*
+     * this function consumes a bit more than "stack" bytes.
+     */
+    if (!wasm_runtime_detect_native_stack_overflow_size(exec_env, 64 + stack)) {
+        return 0;
+    }
     void *base = __builtin_frame_address(0);
     void *base = __builtin_frame_address(0);
     return consume_stack1(exec_env, base, stack);
     return consume_stack1(exec_env, base, stack);
 }
 }