Skip to content

Commit 903a5c1

Browse files
authored
improve logic of heap_type validation when ref.null (#4372)
* Follow-up to PR #4300: prevent potential overflow PR #4300 introduced the rationale for validating heap_type. This patch moves the validation before the computation of type1 to prevent potential overflow.
1 parent fbd27e5 commit 903a5c1

File tree

1 file changed

+33
-16
lines changed

1 file changed

+33
-16
lines changed

core/iwasm/interpreter/wasm_loader.c

Lines changed: 33 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -999,12 +999,10 @@ load_init_expr(WASMModule *module, const uint8 **p_buf, const uint8 *buf_end,
999999
/* ref.null */
10001000
case INIT_EXPR_TYPE_REFNULL_CONST:
10011001
{
1002-
uint8 type1;
1003-
10041002
#if WASM_ENABLE_GC == 0
1003+
uint8 type1;
10051004
CHECK_BUF(p, p_end, 1);
10061005
type1 = read_uint8(p);
1007-
10081006
cur_value.ref_index = NULL_REF;
10091007
if (!push_const_expr_stack(&const_expr_ctx, flag, type1,
10101008
&cur_value,
@@ -1014,23 +1012,34 @@ load_init_expr(WASMModule *module, const uint8 **p_buf, const uint8 *buf_end,
10141012
error_buf, error_buf_size))
10151013
goto fail;
10161014
#else
1015+
/*
1016+
* According to the current GC SPEC rules, the heap_type must be
1017+
* validated when ref.null is used. It can be an absheaptype,
1018+
* or the type C.types[type_idx] must be defined in the context.
1019+
*/
10171020
int32 heap_type;
10181021
read_leb_int32(p, p_end, heap_type);
1019-
type1 = (uint8)((int32)0x80 + heap_type);
1020-
10211022
cur_value.gc_obj = NULL_REF;
10221023

1023-
if (!is_byte_a_type(type1)
1024-
|| !wasm_is_valid_heap_type(heap_type)
1025-
|| wasm_is_type_multi_byte_type(type1)) {
1026-
p--;
1027-
read_leb_uint32(p, p_end, type_idx);
1028-
if (!check_type_index(module, module->type_count, type_idx,
1029-
error_buf, error_buf_size))
1030-
goto fail;
1024+
/*
1025+
* The current check of heap_type can deterministically infer
1026+
* the result of the previous condition
1027+
* `(!is_byte_a_type(type1) ||
1028+
* wasm_is_type_multi_byte_type(type1))`. Therefore, the
1029+
* original condition is redundant and has been removed.
1030+
*
1031+
* This logic is consistent with the implementation of the
1032+
* `WASM_OP_REF_NULL` case in the `wasm_loader_prepare_bytecode`
1033+
* function.
1034+
*/
10311035

1036+
if (heap_type >= 0) {
1037+
if (!check_type_index(module, module->type_count, heap_type,
1038+
error_buf, error_buf_size)) {
1039+
goto fail;
1040+
}
10321041
wasm_set_refheaptype_typeidx(&cur_ref_type.ref_ht_typeidx,
1033-
true, type_idx);
1042+
true, heap_type);
10341043
if (!push_const_expr_stack(&const_expr_ctx, flag,
10351044
cur_ref_type.ref_type,
10361045
&cur_ref_type, 0, &cur_value,
@@ -1041,8 +1050,16 @@ load_init_expr(WASMModule *module, const uint8 **p_buf, const uint8 *buf_end,
10411050
goto fail;
10421051
}
10431052
else {
1044-
if (!push_const_expr_stack(&const_expr_ctx, flag, type1,
1045-
NULL, 0, &cur_value,
1053+
if (!wasm_is_valid_heap_type(heap_type)) {
1054+
set_error_buf_v(error_buf, error_buf_size,
1055+
"unknown type %d", heap_type);
1056+
goto fail;
1057+
}
1058+
cur_ref_type.ref_ht_common.ref_type =
1059+
(uint8)((int32)0x80 + heap_type);
1060+
if (!push_const_expr_stack(&const_expr_ctx, flag,
1061+
cur_ref_type.ref_type, NULL, 0,
1062+
&cur_value,
10461063
#if WASM_ENABLE_EXTENDED_CONST_EXPR != 0
10471064
NULL,
10481065
#endif

0 commit comments

Comments
 (0)