Skip to content

Commit 4269277

Browse files
wenyonghvickiegpt
authored andcommitted
Enhance wasm loader checks for opcode br_table (bytecodealliance#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. Signed-off-by: victoryang00 <[email protected]>
1 parent 90377ae commit 4269277

File tree

2 files changed

+34
-27
lines changed

2 files changed

+34
-27
lines changed

core/iwasm/interpreter/wasm_loader.c

Lines changed: 13 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -293,7 +293,10 @@ type2str(uint8 type)
293293
static bool
294294
is_32bit_type(uint8 type)
295295
{
296-
if (type == VALUE_TYPE_I32 || type == VALUE_TYPE_F32
296+
if (type == VALUE_TYPE_I32
297+
|| type == VALUE_TYPE_F32
298+
/* the operand stack is in polymorphic state */
299+
|| type == VALUE_TYPE_ANY
297300
#if WASM_ENABLE_GC != 0
298301
|| (sizeof(uintptr_t) == 4 && wasm_is_type_reftype(type))
299302
#elif WASM_ENABLE_REF_TYPES != 0
@@ -11533,16 +11536,17 @@ wasm_loader_prepare_bytecode(WASMModule *module, WASMFunction *func,
1153311536
#endif
1153411537
POP_I32();
1153511538

11536-
/* Get the default depth and check it */
11539+
/* Get each depth and check it */
1153711540
p_org = p;
1153811541
for (i = 0; i <= count; i++) {
1153911542
read_leb_uint32(p, p_end, depth);
11540-
}
11541-
if (loader_ctx->csp_num < depth + 1) {
11542-
set_error_buf(error_buf, error_buf_size,
11543-
"unknown label, "
11544-
"unexpected end of section or function");
11545-
goto fail;
11543+
bh_assert(loader_ctx->csp_num > 0);
11544+
if (loader_ctx->csp_num - 1 < depth) {
11545+
set_error_buf(error_buf, error_buf_size,
11546+
"unknown label, "
11547+
"unexpected end of section or function");
11548+
goto fail;
11549+
}
1154611550
}
1154711551
p = p_org;
1154811552

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

1156911567
/* Get the target block's arity and check it */
@@ -11965,8 +11963,7 @@ wasm_loader_prepare_bytecode(WASMModule *module, WASMFunction *func,
1196511963
loader_ctx->reftype_map_num--;
1196611964
}
1196711965
#endif
11968-
if (is_32bit_type(*(loader_ctx->frame_ref - 1))
11969-
|| *(loader_ctx->frame_ref - 1) == VALUE_TYPE_ANY) {
11966+
if (is_32bit_type(*(loader_ctx->frame_ref - 1))) {
1197011967
loader_ctx->frame_ref--;
1197111968
loader_ctx->stack_cell_num--;
1197211969
#if WASM_ENABLE_FAST_INTERP != 0

core/iwasm/interpreter/wasm_mini_loader.c

Lines changed: 21 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -67,7 +67,10 @@ set_error_buf(char *error_buf, uint32 error_buf_size, const char *string)
6767
static bool
6868
is_32bit_type(uint8 type)
6969
{
70-
if (type == VALUE_TYPE_I32 || type == VALUE_TYPE_F32
70+
if (type == VALUE_TYPE_I32
71+
|| type == VALUE_TYPE_F32
72+
/* the operand stack is in polymorphic state */
73+
|| type == VALUE_TYPE_ANY
7174
#if WASM_ENABLE_REF_TYPES != 0
7275
|| type == VALUE_TYPE_FUNCREF || type == VALUE_TYPE_EXTERNREF
7376
#endif
@@ -4237,7 +4240,7 @@ wasm_loader_pop_frame_ref(WASMLoaderContext *ctx, uint8 type, char *error_buf,
42374240
ctx->frame_ref--;
42384241
ctx->stack_cell_num--;
42394242

4240-
if (is_32bit_type(type) || *ctx->frame_ref == VALUE_TYPE_ANY)
4243+
if (is_32bit_type(type))
42414244
return true;
42424245

42434246
ctx->frame_ref--;
@@ -6351,13 +6354,11 @@ wasm_loader_prepare_bytecode(WASMModule *module, WASMFunction *func,
63516354
case WASM_OP_BR_TABLE:
63526355
{
63536356
uint8 *ret_types = NULL;
6354-
uint32 ret_count = 0;
6357+
uint32 ret_count = 0, depth = 0;
63556358
#if WASM_ENABLE_FAST_INTERP == 0
6356-
uint8 *p_depth_begin, *p_depth;
6357-
uint32 depth, j;
63586359
BrTableCache *br_table_cache = NULL;
6359-
6360-
p_org = p - 1;
6360+
uint8 *p_depth_begin, *p_depth, *p_opcode = p - 1;
6361+
uint32 j;
63616362
#endif
63626363

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

6370+
/* Get each depth and check it */
6371+
p_org = p;
6372+
for (i = 0; i <= count; i++) {
6373+
read_leb_uint32(p, p_end, depth);
6374+
bh_assert(loader_ctx->csp_num > 0);
6375+
bh_assert(loader_ctx->csp_num - 1 >= depth);
6376+
(void)depth;
6377+
}
6378+
p = p_org;
6379+
63696380
#if WASM_ENABLE_FAST_INTERP == 0
63706381
p_depth_begin = p_depth = p;
63716382
#endif
@@ -6391,8 +6402,8 @@ wasm_loader_prepare_bytecode(WASMModule *module, WASMFunction *func,
63916402
error_buf, error_buf_size))) {
63926403
goto fail;
63936404
}
6394-
*p_org = EXT_OP_BR_TABLE_CACHE;
6395-
br_table_cache->br_table_op_addr = p_org;
6405+
*p_opcode = EXT_OP_BR_TABLE_CACHE;
6406+
br_table_cache->br_table_op_addr = p_opcode;
63966407
br_table_cache->br_count = count;
63976408
/* Copy previous depths which are one byte */
63986409
for (j = 0; j < i; j++) {
@@ -6623,8 +6634,7 @@ wasm_loader_prepare_bytecode(WASMModule *module, WASMFunction *func,
66236634
&& !cur_block->is_stack_polymorphic));
66246635

66256636
if (available_stack_cell > 0) {
6626-
if (is_32bit_type(*(loader_ctx->frame_ref - 1))
6627-
|| *(loader_ctx->frame_ref - 1) == VALUE_TYPE_ANY) {
6637+
if (is_32bit_type(*(loader_ctx->frame_ref - 1))) {
66286638
loader_ctx->frame_ref--;
66296639
loader_ctx->stack_cell_num--;
66306640
#if WASM_ENABLE_FAST_INTERP != 0

0 commit comments

Comments
 (0)