mirror of
https://github.com/bytecodealliance/wasm-micro-runtime.git
synced 2025-02-06 15:05:19 +00:00
Enhance wasm loader checks for opcode br_table (#3352)
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.
This commit is contained in:
parent
a36c7d5aa9
commit
e44465d259
|
@ -293,7 +293,10 @@ type2str(uint8 type)
|
||||||
static bool
|
static bool
|
||||||
is_32bit_type(uint8 type)
|
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
|
#if WASM_ENABLE_GC != 0
|
||||||
|| (sizeof(uintptr_t) == 4 && wasm_is_type_reftype(type))
|
|| (sizeof(uintptr_t) == 4 && wasm_is_type_reftype(type))
|
||||||
#elif WASM_ENABLE_REF_TYPES != 0
|
#elif WASM_ENABLE_REF_TYPES != 0
|
||||||
|
@ -11533,16 +11536,17 @@ re_scan:
|
||||||
#endif
|
#endif
|
||||||
POP_I32();
|
POP_I32();
|
||||||
|
|
||||||
/* Get the default depth and check it */
|
/* Get each depth and check it */
|
||||||
p_org = p;
|
p_org = p;
|
||||||
for (i = 0; i <= count; i++) {
|
for (i = 0; i <= count; i++) {
|
||||||
read_leb_uint32(p, p_end, depth);
|
read_leb_uint32(p, p_end, depth);
|
||||||
}
|
bh_assert(loader_ctx->csp_num > 0);
|
||||||
if (loader_ctx->csp_num < depth + 1) {
|
if (loader_ctx->csp_num - 1 < depth) {
|
||||||
set_error_buf(error_buf, error_buf_size,
|
set_error_buf(error_buf, error_buf_size,
|
||||||
"unknown label, "
|
"unknown label, "
|
||||||
"unexpected end of section or function");
|
"unexpected end of section or function");
|
||||||
goto fail;
|
goto fail;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
p = p_org;
|
p = p_org;
|
||||||
|
|
||||||
|
@ -11558,12 +11562,6 @@ re_scan:
|
||||||
for (i = 0; i <= count; i++) {
|
for (i = 0; i <= count; i++) {
|
||||||
p_org = p;
|
p_org = p;
|
||||||
read_leb_uint32(p, p_end, depth);
|
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;
|
p = p_org;
|
||||||
|
|
||||||
/* Get the target block's arity and check it */
|
/* Get the target block's arity and check it */
|
||||||
|
@ -11965,8 +11963,7 @@ re_scan:
|
||||||
loader_ctx->reftype_map_num--;
|
loader_ctx->reftype_map_num--;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
if (is_32bit_type(*(loader_ctx->frame_ref - 1))
|
if (is_32bit_type(*(loader_ctx->frame_ref - 1))) {
|
||||||
|| *(loader_ctx->frame_ref - 1) == VALUE_TYPE_ANY) {
|
|
||||||
loader_ctx->frame_ref--;
|
loader_ctx->frame_ref--;
|
||||||
loader_ctx->stack_cell_num--;
|
loader_ctx->stack_cell_num--;
|
||||||
#if WASM_ENABLE_FAST_INTERP != 0
|
#if WASM_ENABLE_FAST_INTERP != 0
|
||||||
|
|
|
@ -67,7 +67,10 @@ set_error_buf(char *error_buf, uint32 error_buf_size, const char *string)
|
||||||
static bool
|
static bool
|
||||||
is_32bit_type(uint8 type)
|
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
|
#if WASM_ENABLE_REF_TYPES != 0
|
||||||
|| type == VALUE_TYPE_FUNCREF || type == VALUE_TYPE_EXTERNREF
|
|| type == VALUE_TYPE_FUNCREF || type == VALUE_TYPE_EXTERNREF
|
||||||
#endif
|
#endif
|
||||||
|
@ -4237,7 +4240,7 @@ wasm_loader_pop_frame_ref(WASMLoaderContext *ctx, uint8 type, char *error_buf,
|
||||||
ctx->frame_ref--;
|
ctx->frame_ref--;
|
||||||
ctx->stack_cell_num--;
|
ctx->stack_cell_num--;
|
||||||
|
|
||||||
if (is_32bit_type(type) || *ctx->frame_ref == VALUE_TYPE_ANY)
|
if (is_32bit_type(type))
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
ctx->frame_ref--;
|
ctx->frame_ref--;
|
||||||
|
@ -6351,13 +6354,11 @@ re_scan:
|
||||||
case WASM_OP_BR_TABLE:
|
case WASM_OP_BR_TABLE:
|
||||||
{
|
{
|
||||||
uint8 *ret_types = NULL;
|
uint8 *ret_types = NULL;
|
||||||
uint32 ret_count = 0;
|
uint32 ret_count = 0, depth = 0;
|
||||||
#if WASM_ENABLE_FAST_INTERP == 0
|
#if WASM_ENABLE_FAST_INTERP == 0
|
||||||
uint8 *p_depth_begin, *p_depth;
|
|
||||||
uint32 depth, j;
|
|
||||||
BrTableCache *br_table_cache = NULL;
|
BrTableCache *br_table_cache = NULL;
|
||||||
|
uint8 *p_depth_begin, *p_depth, *p_opcode = p - 1;
|
||||||
p_org = p - 1;
|
uint32 j;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
read_leb_uint32(p, p_end, count);
|
read_leb_uint32(p, p_end, count);
|
||||||
|
@ -6366,6 +6367,16 @@ re_scan:
|
||||||
#endif
|
#endif
|
||||||
POP_I32();
|
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
|
#if WASM_ENABLE_FAST_INTERP == 0
|
||||||
p_depth_begin = p_depth = p;
|
p_depth_begin = p_depth = p;
|
||||||
#endif
|
#endif
|
||||||
|
@ -6391,8 +6402,8 @@ re_scan:
|
||||||
error_buf, error_buf_size))) {
|
error_buf, error_buf_size))) {
|
||||||
goto fail;
|
goto fail;
|
||||||
}
|
}
|
||||||
*p_org = EXT_OP_BR_TABLE_CACHE;
|
*p_opcode = EXT_OP_BR_TABLE_CACHE;
|
||||||
br_table_cache->br_table_op_addr = p_org;
|
br_table_cache->br_table_op_addr = p_opcode;
|
||||||
br_table_cache->br_count = count;
|
br_table_cache->br_count = count;
|
||||||
/* Copy previous depths which are one byte */
|
/* Copy previous depths which are one byte */
|
||||||
for (j = 0; j < i; j++) {
|
for (j = 0; j < i; j++) {
|
||||||
|
@ -6623,8 +6634,7 @@ re_scan:
|
||||||
&& !cur_block->is_stack_polymorphic));
|
&& !cur_block->is_stack_polymorphic));
|
||||||
|
|
||||||
if (available_stack_cell > 0) {
|
if (available_stack_cell > 0) {
|
||||||
if (is_32bit_type(*(loader_ctx->frame_ref - 1))
|
if (is_32bit_type(*(loader_ctx->frame_ref - 1))) {
|
||||||
|| *(loader_ctx->frame_ref - 1) == VALUE_TYPE_ANY) {
|
|
||||||
loader_ctx->frame_ref--;
|
loader_ctx->frame_ref--;
|
||||||
loader_ctx->stack_cell_num--;
|
loader_ctx->stack_cell_num--;
|
||||||
#if WASM_ENABLE_FAST_INTERP != 0
|
#if WASM_ENABLE_FAST_INTERP != 0
|
||||||
|
|
Loading…
Reference in New Issue
Block a user