diff --git a/core/iwasm/interpreter/wasm_interp_classic.c b/core/iwasm/interpreter/wasm_interp_classic.c index 3312c673a..95417f53b 100644 --- a/core/iwasm/interpreter/wasm_interp_classic.c +++ b/core/iwasm/interpreter/wasm_interp_classic.c @@ -548,11 +548,11 @@ trunc_f32_to_int(WASMModuleInstance *module, uint32 *frame_sp, float32 src_min, if (!saturating) { if (isnan(src_value)) { wasm_set_exception(module, "invalid conversion to integer"); - return true; + return false; } else if (src_value <= src_min || src_value >= src_max) { wasm_set_exception(module, "integer overflow"); - return true; + return false; } } @@ -570,7 +570,7 @@ trunc_f32_to_int(WASMModuleInstance *module, uint32 *frame_sp, float32 src_min, dst_max, is_sign); PUSH_I64(dst_value_i64); } - return false; + return true; } static bool @@ -584,11 +584,11 @@ trunc_f64_to_int(WASMModuleInstance *module, uint32 *frame_sp, float64 src_min, if (!saturating) { if (isnan(src_value)) { wasm_set_exception(module, "invalid conversion to integer"); - return true; + return false; } else if (src_value <= src_min || src_value >= src_max) { wasm_set_exception(module, "integer overflow"); - return true; + return false; } } @@ -606,21 +606,21 @@ trunc_f64_to_int(WASMModuleInstance *module, uint32 *frame_sp, float64 src_min, dst_max, is_sign); PUSH_I64(dst_value_i64); } - return false; + return true; } -#define DEF_OP_TRUNC_F32(min, max, is_i32, is_sign) \ - do { \ - if (trunc_f32_to_int(module, frame_sp, min, max, false, is_i32, \ - is_sign)) \ - goto got_exception; \ +#define DEF_OP_TRUNC_F32(min, max, is_i32, is_sign) \ + do { \ + if (!trunc_f32_to_int(module, frame_sp, min, max, false, is_i32, \ + is_sign)) \ + goto got_exception; \ } while (0) -#define DEF_OP_TRUNC_F64(min, max, is_i32, is_sign) \ - do { \ - if (trunc_f64_to_int(module, frame_sp, min, max, false, is_i32, \ - is_sign)) \ - goto got_exception; \ +#define DEF_OP_TRUNC_F64(min, max, is_i32, is_sign) \ + do { \ + if (!trunc_f64_to_int(module, frame_sp, min, max, false, is_i32, \ + is_sign)) \ + goto got_exception; \ } while (0) #define DEF_OP_TRUNC_SAT_F32(min, max, is_i32, is_sign) \ @@ -1110,7 +1110,7 @@ wasm_interp_call_func_bytecode(WASMModuleInstance *module, uint8 *frame_ip_end = frame_ip + 1; uint8 opcode; uint32 i, depth, cond, count, fidx, tidx, lidx, frame_size = 0; - uint64 all_cell_num = 0; + uint32 all_cell_num = 0; int32 val; uint8 *else_addr, *end_addr, *maddr = NULL; uint32 local_idx, local_offset, global_idx; @@ -3744,7 +3744,7 @@ wasm_interp_call_func_bytecode(WASMModuleInstance *module, word_copy(frame->lp, frame_sp, cur_func->param_cell_num); } FREE_FRAME(exec_env, frame); - wasm_exec_env_set_cur_frame(exec_env, (WASMRuntimeFrame *)prev_frame); + wasm_exec_env_set_cur_frame(exec_env, prev_frame); goto call_func_from_entry; } #endif @@ -3796,17 +3796,16 @@ wasm_interp_call_func_bytecode(WASMModuleInstance *module, func_type = cur_wasm_func->func_type; - all_cell_num = (uint64)cur_func->param_cell_num - + (uint64)cur_func->local_cell_num - + (uint64)cur_wasm_func->max_stack_cell_num - + ((uint64)cur_wasm_func->max_block_num) - * sizeof(WASMBranchBlock) / 4; - if (all_cell_num >= UINT32_MAX) { - wasm_set_exception(module, "wasm operand stack overflow"); - goto got_exception; - } + all_cell_num = cur_func->param_cell_num + cur_func->local_cell_num + + cur_wasm_func->max_stack_cell_num + + cur_wasm_func->max_block_num + * (uint32)sizeof(WASMBranchBlock) / 4; + /* param_cell_num, local_cell_num, max_stack_cell_num and + max_block_num are all no larger than UINT16_MAX (checked + in loader), all_cell_num must be smaller than 1MB */ + bh_assert(all_cell_num < 1 * BH_MB); - frame_size = wasm_interp_interp_frame_size((uint32)all_cell_num); + frame_size = wasm_interp_interp_frame_size(all_cell_num); if (!(frame = ALLOC_FRAME(exec_env, frame_size, prev_frame))) { frame = prev_frame; goto got_exception; @@ -3836,7 +3835,7 @@ wasm_interp_call_func_bytecode(WASMModuleInstance *module, cell_num = func_type->ret_cell_num; PUSH_CSP(LABEL_TYPE_FUNCTION, 0, cell_num, frame_ip_end - 1); - wasm_exec_env_set_cur_frame(exec_env, (WASMRuntimeFrame *)frame); + wasm_exec_env_set_cur_frame(exec_env, frame); #if WASM_ENABLE_THREAD_MGR != 0 CHECK_SUSPEND_FLAGS(); #endif @@ -3847,7 +3846,7 @@ wasm_interp_call_func_bytecode(WASMModuleInstance *module, return_func: { FREE_FRAME(exec_env, frame); - wasm_exec_env_set_cur_frame(exec_env, (WASMRuntimeFrame *)prev_frame); + wasm_exec_env_set_cur_frame(exec_env, prev_frame); if (!prev_frame->ip) /* Called from native. */ @@ -3973,6 +3972,7 @@ llvm_jit_call_func_bytecode(WASMModuleInstance *module_inst, #if (WASM_ENABLE_DUMP_CALL_STACK != 0) || (WASM_ENABLE_PERF_PROFILING != 0) if (!llvm_jit_alloc_frame(exec_env, function - module_inst->e->functions)) { wasm_set_exception(module_inst, "wasm operand stack overflow"); + return false; } #endif @@ -4110,8 +4110,7 @@ wasm_interp_call_wasm(WASMModuleInstance *module_inst, WASMExecEnv *exec_env, } #endif - if (!(frame = - ALLOC_FRAME(exec_env, frame_size, (WASMInterpFrame *)prev_frame))) + if (!(frame = ALLOC_FRAME(exec_env, frame_size, prev_frame))) return; outs_area = wasm_exec_env_wasm_stack_top(exec_env); @@ -4120,6 +4119,12 @@ wasm_interp_call_wasm(WASMModuleInstance *module_inst, WASMExecEnv *exec_env, /* There is no local variable. */ frame->sp = frame->lp + 0; + if ((uint8 *)(outs_area->lp + function->param_cell_num) + > exec_env->wasm_stack.s.top_boundary) { + wasm_set_exception(module_inst, "wasm operand stack overflow"); + return; + } + if (argc > 0) word_copy(outs_area->lp, argv, argc); diff --git a/core/iwasm/interpreter/wasm_interp_fast.c b/core/iwasm/interpreter/wasm_interp_fast.c index ef7f2e049..df356d56f 100644 --- a/core/iwasm/interpreter/wasm_interp_fast.c +++ b/core/iwasm/interpreter/wasm_interp_fast.c @@ -592,11 +592,11 @@ trunc_f32_to_int(WASMModuleInstance *module, uint8 *frame_ip, uint32 *frame_lp, if (!saturating) { if (isnan(src_value)) { wasm_set_exception(module, "invalid conversion to integer"); - return true; + return false; } else if (src_value <= src_min || src_value >= src_max) { wasm_set_exception(module, "integer overflow"); - return true; + return false; } } @@ -614,7 +614,7 @@ trunc_f32_to_int(WASMModuleInstance *module, uint8 *frame_ip, uint32 *frame_lp, dst_max, is_sign); SET_OPERAND(I64, 2, dst_value_i64); } - return false; + return true; } static bool @@ -629,11 +629,11 @@ trunc_f64_to_int(WASMModuleInstance *module, uint8 *frame_ip, uint32 *frame_lp, if (!saturating) { if (isnan(src_value)) { wasm_set_exception(module, "invalid conversion to integer"); - return true; + return false; } else if (src_value <= src_min || src_value >= src_max) { wasm_set_exception(module, "integer overflow"); - return true; + return false; } } @@ -651,23 +651,23 @@ trunc_f64_to_int(WASMModuleInstance *module, uint8 *frame_ip, uint32 *frame_lp, dst_max, is_sign); SET_OPERAND(I64, 2, dst_value_i64); } - return false; + return true; } -#define DEF_OP_TRUNC_F32(min, max, is_i32, is_sign) \ - do { \ - if (trunc_f32_to_int(module, frame_ip, frame_lp, min, max, false, \ - is_i32, is_sign)) \ - goto got_exception; \ - frame_ip += 4; \ +#define DEF_OP_TRUNC_F32(min, max, is_i32, is_sign) \ + do { \ + if (!trunc_f32_to_int(module, frame_ip, frame_lp, min, max, false, \ + is_i32, is_sign)) \ + goto got_exception; \ + frame_ip += 4; \ } while (0) -#define DEF_OP_TRUNC_F64(min, max, is_i32, is_sign) \ - do { \ - if (trunc_f64_to_int(module, frame_ip, frame_lp, min, max, false, \ - is_i32, is_sign)) \ - goto got_exception; \ - frame_ip += 4; \ +#define DEF_OP_TRUNC_F64(min, max, is_i32, is_sign) \ + do { \ + if (!trunc_f64_to_int(module, frame_ip, frame_lp, min, max, false, \ + is_i32, is_sign)) \ + goto got_exception; \ + frame_ip += 4; \ } while (0) #define DEF_OP_TRUNC_SAT_F32(min, max, is_i32, is_sign) \ @@ -1169,7 +1169,7 @@ wasm_interp_call_func_bytecode(WASMModuleInstance *module, #endif uint8 *frame_ip_end = frame_ip + 1; uint32 cond, count, fidx, tidx, frame_size = 0; - uint64 all_cell_num = 0; + uint32 all_cell_num = 0; int16 addr1, addr2, addr_ret = 0; int32 didx, val; uint8 *maddr = NULL; @@ -3780,16 +3780,15 @@ wasm_interp_call_func_bytecode(WASMModuleInstance *module, else { WASMFunction *cur_wasm_func = cur_func->u.func; - all_cell_num = (uint64)cur_func->param_cell_num - + (uint64)cur_func->local_cell_num - + (uint64)cur_func->const_cell_num - + (uint64)cur_wasm_func->max_stack_cell_num; - if (all_cell_num >= UINT32_MAX) { - wasm_set_exception(module, "wasm operand stack overflow"); - goto got_exception; - } + all_cell_num = cur_func->param_cell_num + cur_func->local_cell_num + + cur_func->const_cell_num + + cur_wasm_func->max_stack_cell_num; + /* param_cell_num, local_cell_num, const_cell_num and + max_stack_cell_num are all no larger than UINT16_MAX (checked + in loader), all_cell_num must be smaller than 1MB */ + bh_assert(all_cell_num < 1 * BH_MB); - frame_size = wasm_interp_interp_frame_size((uint32)all_cell_num); + frame_size = wasm_interp_interp_frame_size(all_cell_num); if (!(frame = ALLOC_FRAME(exec_env, frame_size, prev_frame))) { frame = prev_frame; goto got_exception; diff --git a/core/iwasm/interpreter/wasm_loader.c b/core/iwasm/interpreter/wasm_loader.c index c706b6c7d..efd3fb859 100644 --- a/core/iwasm/interpreter/wasm_loader.c +++ b/core/iwasm/interpreter/wasm_loader.c @@ -5078,8 +5078,14 @@ wasm_loader_push_frame_ref(WASMLoaderContext *ctx, uint8 type, char *error_buf, #endif check_stack_and_return: - if (ctx->stack_cell_num > ctx->max_stack_cell_num) + if (ctx->stack_cell_num > ctx->max_stack_cell_num) { ctx->max_stack_cell_num = ctx->stack_cell_num; + if (ctx->max_stack_cell_num > UINT16_MAX) { + set_error_buf(error_buf, error_buf_size, + "operand stack depth limit exceeded"); + return false; + } + } return true; } @@ -5154,8 +5160,14 @@ wasm_loader_push_frame_csp(WASMLoaderContext *ctx, uint8 label_type, #endif ctx->frame_csp++; ctx->csp_num++; - if (ctx->csp_num > ctx->max_csp_num) + if (ctx->csp_num > ctx->max_csp_num) { ctx->max_csp_num = ctx->csp_num; + if (ctx->max_csp_num > UINT16_MAX) { + set_error_buf(error_buf, error_buf_size, + "label stack depth limit exceeded"); + return false; + } + } return true; fail: return false; diff --git a/core/iwasm/interpreter/wasm_mini_loader.c b/core/iwasm/interpreter/wasm_mini_loader.c index f96a90728..0f37c9983 100644 --- a/core/iwasm/interpreter/wasm_mini_loader.c +++ b/core/iwasm/interpreter/wasm_mini_loader.c @@ -3594,8 +3594,10 @@ wasm_loader_push_frame_ref(WASMLoaderContext *ctx, uint8 type, char *error_buf, return false; *ctx->frame_ref++ = type; ctx->stack_cell_num++; - if (ctx->stack_cell_num > ctx->max_stack_cell_num) + if (ctx->stack_cell_num > ctx->max_stack_cell_num) { ctx->max_stack_cell_num = ctx->stack_cell_num; + bh_assert(ctx->max_stack_cell_num <= UINT16_MAX); + } return true; } @@ -3661,8 +3663,10 @@ wasm_loader_push_frame_csp(WASMLoaderContext *ctx, uint8 label_type, #endif ctx->frame_csp++; ctx->csp_num++; - if (ctx->csp_num > ctx->max_csp_num) + if (ctx->csp_num > ctx->max_csp_num) { ctx->max_csp_num = ctx->csp_num; + bh_assert(ctx->max_csp_num <= UINT16_MAX); + } return true; fail: return false;