Skip to content

Commit

Permalink
Enhance wasm loader checks for opcode br_table (#3352)
Browse files Browse the repository at this point in the history
Fix the integer overflow issue when checking target branch depth in opcode
br_table, and fix is_32bit_type not check VALUE_TYPE_ANY issue, which may
cause wasm_loader_push_frame_offset push extra unneeded offset.
  • Loading branch information
wenyongh committed Apr 25, 2024
1 parent a36c7d5 commit e44465d
Show file tree
Hide file tree
Showing 2 changed files with 34 additions and 27 deletions.
29 changes: 13 additions & 16 deletions core/iwasm/interpreter/wasm_loader.c
Original file line number Diff line number Diff line change
Expand Up @@ -293,7 +293,10 @@ type2str(uint8 type)
static bool
is_32bit_type(uint8 type)
{
if (type == VALUE_TYPE_I32 || type == VALUE_TYPE_F32
if (type == VALUE_TYPE_I32
|| type == VALUE_TYPE_F32
/* the operand stack is in polymorphic state */
|| type == VALUE_TYPE_ANY
#if WASM_ENABLE_GC != 0
|| (sizeof(uintptr_t) == 4 && wasm_is_type_reftype(type))
#elif WASM_ENABLE_REF_TYPES != 0
Expand Down Expand Up @@ -11533,16 +11536,17 @@ wasm_loader_prepare_bytecode(WASMModule *module, WASMFunction *func,
#endif
POP_I32();

/* Get the default depth and check it */
/* Get each depth and check it */
p_org = p;
for (i = 0; i <= count; i++) {
read_leb_uint32(p, p_end, depth);
}
if (loader_ctx->csp_num < depth + 1) {
set_error_buf(error_buf, error_buf_size,
"unknown label, "
"unexpected end of section or function");
goto fail;
bh_assert(loader_ctx->csp_num > 0);
if (loader_ctx->csp_num - 1 < depth) {
set_error_buf(error_buf, error_buf_size,
"unknown label, "
"unexpected end of section or function");
goto fail;
}
}
p = p_org;

Expand All @@ -11558,12 +11562,6 @@ wasm_loader_prepare_bytecode(WASMModule *module, WASMFunction *func,
for (i = 0; i <= count; i++) {
p_org = p;
read_leb_uint32(p, p_end, depth);
if (loader_ctx->csp_num < depth + 1) {
set_error_buf(error_buf, error_buf_size,
"unknown label, "
"unexpected end of section or function");
goto fail;
}
p = p_org;

/* Get the target block's arity and check it */
Expand Down Expand Up @@ -11965,8 +11963,7 @@ wasm_loader_prepare_bytecode(WASMModule *module, WASMFunction *func,
loader_ctx->reftype_map_num--;
}
#endif
if (is_32bit_type(*(loader_ctx->frame_ref - 1))
|| *(loader_ctx->frame_ref - 1) == VALUE_TYPE_ANY) {
if (is_32bit_type(*(loader_ctx->frame_ref - 1))) {
loader_ctx->frame_ref--;
loader_ctx->stack_cell_num--;
#if WASM_ENABLE_FAST_INTERP != 0
Expand Down
32 changes: 21 additions & 11 deletions core/iwasm/interpreter/wasm_mini_loader.c
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,10 @@ set_error_buf(char *error_buf, uint32 error_buf_size, const char *string)
static bool
is_32bit_type(uint8 type)
{
if (type == VALUE_TYPE_I32 || type == VALUE_TYPE_F32
if (type == VALUE_TYPE_I32
|| type == VALUE_TYPE_F32
/* the operand stack is in polymorphic state */
|| type == VALUE_TYPE_ANY
#if WASM_ENABLE_REF_TYPES != 0
|| type == VALUE_TYPE_FUNCREF || type == VALUE_TYPE_EXTERNREF
#endif
Expand Down Expand Up @@ -4237,7 +4240,7 @@ wasm_loader_pop_frame_ref(WASMLoaderContext *ctx, uint8 type, char *error_buf,
ctx->frame_ref--;
ctx->stack_cell_num--;

if (is_32bit_type(type) || *ctx->frame_ref == VALUE_TYPE_ANY)
if (is_32bit_type(type))
return true;

ctx->frame_ref--;
Expand Down Expand Up @@ -6351,13 +6354,11 @@ wasm_loader_prepare_bytecode(WASMModule *module, WASMFunction *func,
case WASM_OP_BR_TABLE:
{
uint8 *ret_types = NULL;
uint32 ret_count = 0;
uint32 ret_count = 0, depth = 0;
#if WASM_ENABLE_FAST_INTERP == 0
uint8 *p_depth_begin, *p_depth;
uint32 depth, j;
BrTableCache *br_table_cache = NULL;

p_org = p - 1;
uint8 *p_depth_begin, *p_depth, *p_opcode = p - 1;
uint32 j;
#endif

read_leb_uint32(p, p_end, count);
Expand All @@ -6366,6 +6367,16 @@ wasm_loader_prepare_bytecode(WASMModule *module, WASMFunction *func,
#endif
POP_I32();

/* Get each depth and check it */
p_org = p;
for (i = 0; i <= count; i++) {
read_leb_uint32(p, p_end, depth);
bh_assert(loader_ctx->csp_num > 0);
bh_assert(loader_ctx->csp_num - 1 >= depth);
(void)depth;
}
p = p_org;

#if WASM_ENABLE_FAST_INTERP == 0
p_depth_begin = p_depth = p;
#endif
Expand All @@ -6391,8 +6402,8 @@ wasm_loader_prepare_bytecode(WASMModule *module, WASMFunction *func,
error_buf, error_buf_size))) {
goto fail;
}
*p_org = EXT_OP_BR_TABLE_CACHE;
br_table_cache->br_table_op_addr = p_org;
*p_opcode = EXT_OP_BR_TABLE_CACHE;
br_table_cache->br_table_op_addr = p_opcode;
br_table_cache->br_count = count;
/* Copy previous depths which are one byte */
for (j = 0; j < i; j++) {
Expand Down Expand Up @@ -6623,8 +6634,7 @@ wasm_loader_prepare_bytecode(WASMModule *module, WASMFunction *func,
&& !cur_block->is_stack_polymorphic));

if (available_stack_cell > 0) {
if (is_32bit_type(*(loader_ctx->frame_ref - 1))
|| *(loader_ctx->frame_ref - 1) == VALUE_TYPE_ANY) {
if (is_32bit_type(*(loader_ctx->frame_ref - 1))) {
loader_ctx->frame_ref--;
loader_ctx->stack_cell_num--;
#if WASM_ENABLE_FAST_INTERP != 0
Expand Down

0 comments on commit e44465d

Please sign in to comment.