mirror of
https://github.com/bytecodealliance/wasm-micro-runtime.git
synced 2025-02-11 17:35:13 +00:00
Refine the stack frame size check in interpreter (#1730)
Limit max_stack_cell_num/max_csp_num to be no larger than UINT16_MAX, and don't check all_cell_num in interpreter again. And refine some codes in interpreter.
This commit is contained in:
parent
656a8427e6
commit
da7117a092
|
@ -548,11 +548,11 @@ trunc_f32_to_int(WASMModuleInstance *module, uint32 *frame_sp, float32 src_min,
|
||||||
if (!saturating) {
|
if (!saturating) {
|
||||||
if (isnan(src_value)) {
|
if (isnan(src_value)) {
|
||||||
wasm_set_exception(module, "invalid conversion to integer");
|
wasm_set_exception(module, "invalid conversion to integer");
|
||||||
return true;
|
return false;
|
||||||
}
|
}
|
||||||
else if (src_value <= src_min || src_value >= src_max) {
|
else if (src_value <= src_min || src_value >= src_max) {
|
||||||
wasm_set_exception(module, "integer overflow");
|
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);
|
dst_max, is_sign);
|
||||||
PUSH_I64(dst_value_i64);
|
PUSH_I64(dst_value_i64);
|
||||||
}
|
}
|
||||||
return false;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool
|
static bool
|
||||||
|
@ -584,11 +584,11 @@ trunc_f64_to_int(WASMModuleInstance *module, uint32 *frame_sp, float64 src_min,
|
||||||
if (!saturating) {
|
if (!saturating) {
|
||||||
if (isnan(src_value)) {
|
if (isnan(src_value)) {
|
||||||
wasm_set_exception(module, "invalid conversion to integer");
|
wasm_set_exception(module, "invalid conversion to integer");
|
||||||
return true;
|
return false;
|
||||||
}
|
}
|
||||||
else if (src_value <= src_min || src_value >= src_max) {
|
else if (src_value <= src_min || src_value >= src_max) {
|
||||||
wasm_set_exception(module, "integer overflow");
|
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);
|
dst_max, is_sign);
|
||||||
PUSH_I64(dst_value_i64);
|
PUSH_I64(dst_value_i64);
|
||||||
}
|
}
|
||||||
return false;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
#define DEF_OP_TRUNC_F32(min, max, is_i32, is_sign) \
|
#define DEF_OP_TRUNC_F32(min, max, is_i32, is_sign) \
|
||||||
do { \
|
do { \
|
||||||
if (trunc_f32_to_int(module, frame_sp, min, max, false, is_i32, \
|
if (!trunc_f32_to_int(module, frame_sp, min, max, false, is_i32, \
|
||||||
is_sign)) \
|
is_sign)) \
|
||||||
goto got_exception; \
|
goto got_exception; \
|
||||||
} while (0)
|
} while (0)
|
||||||
|
|
||||||
#define DEF_OP_TRUNC_F64(min, max, is_i32, is_sign) \
|
#define DEF_OP_TRUNC_F64(min, max, is_i32, is_sign) \
|
||||||
do { \
|
do { \
|
||||||
if (trunc_f64_to_int(module, frame_sp, min, max, false, is_i32, \
|
if (!trunc_f64_to_int(module, frame_sp, min, max, false, is_i32, \
|
||||||
is_sign)) \
|
is_sign)) \
|
||||||
goto got_exception; \
|
goto got_exception; \
|
||||||
} while (0)
|
} while (0)
|
||||||
|
|
||||||
#define DEF_OP_TRUNC_SAT_F32(min, max, is_i32, is_sign) \
|
#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 *frame_ip_end = frame_ip + 1;
|
||||||
uint8 opcode;
|
uint8 opcode;
|
||||||
uint32 i, depth, cond, count, fidx, tidx, lidx, frame_size = 0;
|
uint32 i, depth, cond, count, fidx, tidx, lidx, frame_size = 0;
|
||||||
uint64 all_cell_num = 0;
|
uint32 all_cell_num = 0;
|
||||||
int32 val;
|
int32 val;
|
||||||
uint8 *else_addr, *end_addr, *maddr = NULL;
|
uint8 *else_addr, *end_addr, *maddr = NULL;
|
||||||
uint32 local_idx, local_offset, global_idx;
|
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);
|
word_copy(frame->lp, frame_sp, cur_func->param_cell_num);
|
||||||
}
|
}
|
||||||
FREE_FRAME(exec_env, frame);
|
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;
|
goto call_func_from_entry;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
@ -3796,17 +3796,16 @@ wasm_interp_call_func_bytecode(WASMModuleInstance *module,
|
||||||
|
|
||||||
func_type = cur_wasm_func->func_type;
|
func_type = cur_wasm_func->func_type;
|
||||||
|
|
||||||
all_cell_num = (uint64)cur_func->param_cell_num
|
all_cell_num = cur_func->param_cell_num + cur_func->local_cell_num
|
||||||
+ (uint64)cur_func->local_cell_num
|
+ cur_wasm_func->max_stack_cell_num
|
||||||
+ (uint64)cur_wasm_func->max_stack_cell_num
|
+ cur_wasm_func->max_block_num
|
||||||
+ ((uint64)cur_wasm_func->max_block_num)
|
* (uint32)sizeof(WASMBranchBlock) / 4;
|
||||||
* sizeof(WASMBranchBlock) / 4;
|
/* param_cell_num, local_cell_num, max_stack_cell_num and
|
||||||
if (all_cell_num >= UINT32_MAX) {
|
max_block_num are all no larger than UINT16_MAX (checked
|
||||||
wasm_set_exception(module, "wasm operand stack overflow");
|
in loader), all_cell_num must be smaller than 1MB */
|
||||||
goto got_exception;
|
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))) {
|
if (!(frame = ALLOC_FRAME(exec_env, frame_size, prev_frame))) {
|
||||||
frame = prev_frame;
|
frame = prev_frame;
|
||||||
goto got_exception;
|
goto got_exception;
|
||||||
|
@ -3836,7 +3835,7 @@ wasm_interp_call_func_bytecode(WASMModuleInstance *module,
|
||||||
cell_num = func_type->ret_cell_num;
|
cell_num = func_type->ret_cell_num;
|
||||||
PUSH_CSP(LABEL_TYPE_FUNCTION, 0, cell_num, frame_ip_end - 1);
|
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
|
#if WASM_ENABLE_THREAD_MGR != 0
|
||||||
CHECK_SUSPEND_FLAGS();
|
CHECK_SUSPEND_FLAGS();
|
||||||
#endif
|
#endif
|
||||||
|
@ -3847,7 +3846,7 @@ wasm_interp_call_func_bytecode(WASMModuleInstance *module,
|
||||||
return_func:
|
return_func:
|
||||||
{
|
{
|
||||||
FREE_FRAME(exec_env, frame);
|
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)
|
if (!prev_frame->ip)
|
||||||
/* Called from native. */
|
/* 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 (WASM_ENABLE_DUMP_CALL_STACK != 0) || (WASM_ENABLE_PERF_PROFILING != 0)
|
||||||
if (!llvm_jit_alloc_frame(exec_env, function - module_inst->e->functions)) {
|
if (!llvm_jit_alloc_frame(exec_env, function - module_inst->e->functions)) {
|
||||||
wasm_set_exception(module_inst, "wasm operand stack overflow");
|
wasm_set_exception(module_inst, "wasm operand stack overflow");
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
@ -4110,8 +4110,7 @@ wasm_interp_call_wasm(WASMModuleInstance *module_inst, WASMExecEnv *exec_env,
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if (!(frame =
|
if (!(frame = ALLOC_FRAME(exec_env, frame_size, prev_frame)))
|
||||||
ALLOC_FRAME(exec_env, frame_size, (WASMInterpFrame *)prev_frame)))
|
|
||||||
return;
|
return;
|
||||||
|
|
||||||
outs_area = wasm_exec_env_wasm_stack_top(exec_env);
|
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. */
|
/* There is no local variable. */
|
||||||
frame->sp = frame->lp + 0;
|
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)
|
if (argc > 0)
|
||||||
word_copy(outs_area->lp, argv, argc);
|
word_copy(outs_area->lp, argv, argc);
|
||||||
|
|
||||||
|
|
|
@ -592,11 +592,11 @@ trunc_f32_to_int(WASMModuleInstance *module, uint8 *frame_ip, uint32 *frame_lp,
|
||||||
if (!saturating) {
|
if (!saturating) {
|
||||||
if (isnan(src_value)) {
|
if (isnan(src_value)) {
|
||||||
wasm_set_exception(module, "invalid conversion to integer");
|
wasm_set_exception(module, "invalid conversion to integer");
|
||||||
return true;
|
return false;
|
||||||
}
|
}
|
||||||
else if (src_value <= src_min || src_value >= src_max) {
|
else if (src_value <= src_min || src_value >= src_max) {
|
||||||
wasm_set_exception(module, "integer overflow");
|
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);
|
dst_max, is_sign);
|
||||||
SET_OPERAND(I64, 2, dst_value_i64);
|
SET_OPERAND(I64, 2, dst_value_i64);
|
||||||
}
|
}
|
||||||
return false;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool
|
static bool
|
||||||
|
@ -629,11 +629,11 @@ trunc_f64_to_int(WASMModuleInstance *module, uint8 *frame_ip, uint32 *frame_lp,
|
||||||
if (!saturating) {
|
if (!saturating) {
|
||||||
if (isnan(src_value)) {
|
if (isnan(src_value)) {
|
||||||
wasm_set_exception(module, "invalid conversion to integer");
|
wasm_set_exception(module, "invalid conversion to integer");
|
||||||
return true;
|
return false;
|
||||||
}
|
}
|
||||||
else if (src_value <= src_min || src_value >= src_max) {
|
else if (src_value <= src_min || src_value >= src_max) {
|
||||||
wasm_set_exception(module, "integer overflow");
|
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);
|
dst_max, is_sign);
|
||||||
SET_OPERAND(I64, 2, dst_value_i64);
|
SET_OPERAND(I64, 2, dst_value_i64);
|
||||||
}
|
}
|
||||||
return false;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
#define DEF_OP_TRUNC_F32(min, max, is_i32, is_sign) \
|
#define DEF_OP_TRUNC_F32(min, max, is_i32, is_sign) \
|
||||||
do { \
|
do { \
|
||||||
if (trunc_f32_to_int(module, frame_ip, frame_lp, min, max, false, \
|
if (!trunc_f32_to_int(module, frame_ip, frame_lp, min, max, false, \
|
||||||
is_i32, is_sign)) \
|
is_i32, is_sign)) \
|
||||||
goto got_exception; \
|
goto got_exception; \
|
||||||
frame_ip += 4; \
|
frame_ip += 4; \
|
||||||
} while (0)
|
} while (0)
|
||||||
|
|
||||||
#define DEF_OP_TRUNC_F64(min, max, is_i32, is_sign) \
|
#define DEF_OP_TRUNC_F64(min, max, is_i32, is_sign) \
|
||||||
do { \
|
do { \
|
||||||
if (trunc_f64_to_int(module, frame_ip, frame_lp, min, max, false, \
|
if (!trunc_f64_to_int(module, frame_ip, frame_lp, min, max, false, \
|
||||||
is_i32, is_sign)) \
|
is_i32, is_sign)) \
|
||||||
goto got_exception; \
|
goto got_exception; \
|
||||||
frame_ip += 4; \
|
frame_ip += 4; \
|
||||||
} while (0)
|
} while (0)
|
||||||
|
|
||||||
#define DEF_OP_TRUNC_SAT_F32(min, max, is_i32, is_sign) \
|
#define DEF_OP_TRUNC_SAT_F32(min, max, is_i32, is_sign) \
|
||||||
|
@ -1169,7 +1169,7 @@ wasm_interp_call_func_bytecode(WASMModuleInstance *module,
|
||||||
#endif
|
#endif
|
||||||
uint8 *frame_ip_end = frame_ip + 1;
|
uint8 *frame_ip_end = frame_ip + 1;
|
||||||
uint32 cond, count, fidx, tidx, frame_size = 0;
|
uint32 cond, count, fidx, tidx, frame_size = 0;
|
||||||
uint64 all_cell_num = 0;
|
uint32 all_cell_num = 0;
|
||||||
int16 addr1, addr2, addr_ret = 0;
|
int16 addr1, addr2, addr_ret = 0;
|
||||||
int32 didx, val;
|
int32 didx, val;
|
||||||
uint8 *maddr = NULL;
|
uint8 *maddr = NULL;
|
||||||
|
@ -3780,16 +3780,15 @@ wasm_interp_call_func_bytecode(WASMModuleInstance *module,
|
||||||
else {
|
else {
|
||||||
WASMFunction *cur_wasm_func = cur_func->u.func;
|
WASMFunction *cur_wasm_func = cur_func->u.func;
|
||||||
|
|
||||||
all_cell_num = (uint64)cur_func->param_cell_num
|
all_cell_num = cur_func->param_cell_num + cur_func->local_cell_num
|
||||||
+ (uint64)cur_func->local_cell_num
|
+ cur_func->const_cell_num
|
||||||
+ (uint64)cur_func->const_cell_num
|
+ cur_wasm_func->max_stack_cell_num;
|
||||||
+ (uint64)cur_wasm_func->max_stack_cell_num;
|
/* param_cell_num, local_cell_num, const_cell_num and
|
||||||
if (all_cell_num >= UINT32_MAX) {
|
max_stack_cell_num are all no larger than UINT16_MAX (checked
|
||||||
wasm_set_exception(module, "wasm operand stack overflow");
|
in loader), all_cell_num must be smaller than 1MB */
|
||||||
goto got_exception;
|
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))) {
|
if (!(frame = ALLOC_FRAME(exec_env, frame_size, prev_frame))) {
|
||||||
frame = prev_frame;
|
frame = prev_frame;
|
||||||
goto got_exception;
|
goto got_exception;
|
||||||
|
|
|
@ -5078,8 +5078,14 @@ wasm_loader_push_frame_ref(WASMLoaderContext *ctx, uint8 type, char *error_buf,
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
check_stack_and_return:
|
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;
|
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;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -5154,8 +5160,14 @@ wasm_loader_push_frame_csp(WASMLoaderContext *ctx, uint8 label_type,
|
||||||
#endif
|
#endif
|
||||||
ctx->frame_csp++;
|
ctx->frame_csp++;
|
||||||
ctx->csp_num++;
|
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;
|
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;
|
return true;
|
||||||
fail:
|
fail:
|
||||||
return false;
|
return false;
|
||||||
|
|
|
@ -3594,8 +3594,10 @@ wasm_loader_push_frame_ref(WASMLoaderContext *ctx, uint8 type, char *error_buf,
|
||||||
return false;
|
return false;
|
||||||
*ctx->frame_ref++ = type;
|
*ctx->frame_ref++ = type;
|
||||||
ctx->stack_cell_num++;
|
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;
|
ctx->max_stack_cell_num = ctx->stack_cell_num;
|
||||||
|
bh_assert(ctx->max_stack_cell_num <= UINT16_MAX);
|
||||||
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3661,8 +3663,10 @@ wasm_loader_push_frame_csp(WASMLoaderContext *ctx, uint8 label_type,
|
||||||
#endif
|
#endif
|
||||||
ctx->frame_csp++;
|
ctx->frame_csp++;
|
||||||
ctx->csp_num++;
|
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;
|
ctx->max_csp_num = ctx->csp_num;
|
||||||
|
bh_assert(ctx->max_csp_num <= UINT16_MAX);
|
||||||
|
}
|
||||||
return true;
|
return true;
|
||||||
fail:
|
fail:
|
||||||
return false;
|
return false;
|
||||||
|
|
Loading…
Reference in New Issue
Block a user