mirror of
https://github.com/bytecodealliance/wasm-micro-runtime.git
synced 2025-05-12 12:41:25 +00:00
wasm loader: Fix checks for opcode ref.func and opcode else (#3340)
Fix wasm loader integrity checks for opcode ref.func and opcode else: for opcode ref.func, the function must be an import, exported, or present in a table elem segment or global initializer to be used as the operand to ref.func, for opcode else, there must not be an else opcode previously. Reported in #3336 and #3337. And fix mini loader PUSH_MEM_OFFSET/POP_MEM_OFFSET macro definitions due to the introducing of memory64 feature.
This commit is contained in:
parent
a6e008bca7
commit
18d363029c
|
@ -4628,7 +4628,7 @@ load_data_segment_section(const uint8 *buf, const uint8 *buf_end,
|
||||||
bool is_passive = false;
|
bool is_passive = false;
|
||||||
uint32 mem_flag;
|
uint32 mem_flag;
|
||||||
#endif
|
#endif
|
||||||
uint8 mem_offset_type;
|
uint8 mem_offset_type = VALUE_TYPE_I32;
|
||||||
|
|
||||||
read_leb_uint32(p, p_end, data_seg_count);
|
read_leb_uint32(p, p_end, data_seg_count);
|
||||||
|
|
||||||
|
@ -11335,8 +11335,10 @@ re_scan:
|
||||||
BlockType block_type;
|
BlockType block_type;
|
||||||
|
|
||||||
if (loader_ctx->csp_num < 2
|
if (loader_ctx->csp_num < 2
|
||||||
|| (loader_ctx->frame_csp - 1)->label_type
|
/* the matched if isn't found */
|
||||||
!= LABEL_TYPE_IF) {
|
|| (loader_ctx->frame_csp - 1)->label_type != LABEL_TYPE_IF
|
||||||
|
/* duplicated else is found */
|
||||||
|
|| (loader_ctx->frame_csp - 1)->else_addr) {
|
||||||
set_error_buf(
|
set_error_buf(
|
||||||
error_buf, error_buf_size,
|
error_buf, error_buf_size,
|
||||||
"opcode else found without matched opcode if");
|
"opcode else found without matched opcode if");
|
||||||
|
@ -12408,33 +12410,58 @@ re_scan:
|
||||||
goto fail;
|
goto fail;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Refer to a forward-declared function */
|
/* Refer to a forward-declared function:
|
||||||
if (func_idx >= cur_func_idx + module->import_function_count) {
|
the function must be an import, exported, or present in
|
||||||
|
a table elem segment or global initializer to be used as
|
||||||
|
the operand to ref.func */
|
||||||
|
if (func_idx >= module->import_function_count) {
|
||||||
WASMTableSeg *table_seg = module->table_segments;
|
WASMTableSeg *table_seg = module->table_segments;
|
||||||
bool func_declared = false;
|
bool func_declared = false;
|
||||||
uint32 j;
|
uint32 j;
|
||||||
|
|
||||||
/* Check whether the function is declared in table segs,
|
for (i = 0; i < module->global_count; i++) {
|
||||||
note that it doesn't matter whether the table seg's mode
|
if (module->globals[i].type == VALUE_TYPE_FUNCREF
|
||||||
is passive, active or declarative. */
|
&& module->globals[i].init_expr.init_expr_type
|
||||||
for (i = 0; i < module->table_seg_count; i++, table_seg++) {
|
== INIT_EXPR_TYPE_FUNCREF_CONST
|
||||||
if (table_seg->elem_type == VALUE_TYPE_FUNCREF
|
&& module->globals[i].init_expr.u.u32 == func_idx) {
|
||||||
|
func_declared = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!func_declared) {
|
||||||
|
/* Check whether the function is declared in table segs,
|
||||||
|
note that it doesn't matter whether the table seg's
|
||||||
|
mode is passive, active or declarative. */
|
||||||
|
for (i = 0; i < module->table_seg_count;
|
||||||
|
i++, table_seg++) {
|
||||||
|
if (table_seg->elem_type == VALUE_TYPE_FUNCREF
|
||||||
#if WASM_ENABLE_GC != 0
|
#if WASM_ENABLE_GC != 0
|
||||||
|| (table_seg->elem_type == REF_TYPE_HT_NON_NULLABLE
|
/* elem type is (ref null? func) or
|
||||||
&& table_seg->elem_ref_type->ref_ht_common
|
(ref null? $t) */
|
||||||
.heap_type
|
|| ((table_seg->elem_type
|
||||||
== HEAP_TYPE_FUNC)
|
== REF_TYPE_HT_NON_NULLABLE
|
||||||
|
|| table_seg->elem_type
|
||||||
|
== REF_TYPE_HT_NULLABLE)
|
||||||
|
&& (table_seg->elem_ref_type->ref_ht_common
|
||||||
|
.heap_type
|
||||||
|
== HEAP_TYPE_FUNC
|
||||||
|
|| table_seg->elem_ref_type
|
||||||
|
->ref_ht_common.heap_type
|
||||||
|
> 0))
|
||||||
#endif
|
#endif
|
||||||
) {
|
) {
|
||||||
for (j = 0; j < table_seg->value_count; j++) {
|
for (j = 0; j < table_seg->value_count; j++) {
|
||||||
if (table_seg->init_values[j].u.ref_index
|
if (table_seg->init_values[j].u.ref_index
|
||||||
== func_idx) {
|
== func_idx) {
|
||||||
func_declared = true;
|
func_declared = true;
|
||||||
break;
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!func_declared) {
|
if (!func_declared) {
|
||||||
/* Check whether the function is exported */
|
/* Check whether the function is exported */
|
||||||
for (i = 0; i < module->export_count; i++) {
|
for (i = 0; i < module->export_count; i++) {
|
||||||
|
|
|
@ -1776,7 +1776,7 @@ load_data_segment_section(const uint8 *buf, const uint8 *buf_end,
|
||||||
bool is_passive = false;
|
bool is_passive = false;
|
||||||
uint32 mem_flag;
|
uint32 mem_flag;
|
||||||
#endif
|
#endif
|
||||||
uint8 mem_offset_type;
|
uint8 mem_offset_type = VALUE_TYPE_I32;
|
||||||
|
|
||||||
read_leb_uint32(p, p_end, data_seg_count);
|
read_leb_uint32(p, p_end, data_seg_count);
|
||||||
|
|
||||||
|
@ -5179,10 +5179,21 @@ fail:
|
||||||
goto fail; \
|
goto fail; \
|
||||||
} while (0)
|
} while (0)
|
||||||
|
|
||||||
#define PUSH_MEM_OFFSET() PUSH_OFFSET_TYPE(mem_offset_type)
|
#define PUSH_MEM_OFFSET() \
|
||||||
|
do { \
|
||||||
|
if (!wasm_loader_push_frame_ref_offset(loader_ctx, mem_offset_type, \
|
||||||
|
disable_emit, operand_offset, \
|
||||||
|
error_buf, error_buf_size)) \
|
||||||
|
goto fail; \
|
||||||
|
} while (0)
|
||||||
#define PUSH_PAGE_COUNT() PUSH_MEM_OFFSET()
|
#define PUSH_PAGE_COUNT() PUSH_MEM_OFFSET()
|
||||||
|
|
||||||
#define POP_MEM_OFFSET() POP_OFFSET_TYPE(mem_offset_type)
|
#define POP_MEM_OFFSET() \
|
||||||
|
do { \
|
||||||
|
if (!wasm_loader_pop_frame_ref_offset(loader_ctx, mem_offset_type, \
|
||||||
|
error_buf, error_buf_size)) \
|
||||||
|
goto fail; \
|
||||||
|
} while (0)
|
||||||
|
|
||||||
#define POP_AND_PUSH(type_pop, type_push) \
|
#define POP_AND_PUSH(type_pop, type_push) \
|
||||||
do { \
|
do { \
|
||||||
|
@ -6203,8 +6214,11 @@ re_scan:
|
||||||
BranchBlock *block = NULL;
|
BranchBlock *block = NULL;
|
||||||
BlockType block_type = (loader_ctx->frame_csp - 1)->block_type;
|
BlockType block_type = (loader_ctx->frame_csp - 1)->block_type;
|
||||||
bh_assert(loader_ctx->csp_num >= 2
|
bh_assert(loader_ctx->csp_num >= 2
|
||||||
|
/* the matched if is found */
|
||||||
&& (loader_ctx->frame_csp - 1)->label_type
|
&& (loader_ctx->frame_csp - 1)->label_type
|
||||||
== LABEL_TYPE_IF);
|
== LABEL_TYPE_IF
|
||||||
|
/* duplicated else isn't found */
|
||||||
|
&& !(loader_ctx->frame_csp - 1)->else_addr);
|
||||||
block = loader_ctx->frame_csp - 1;
|
block = loader_ctx->frame_csp - 1;
|
||||||
|
|
||||||
/* check whether if branch's stack matches its result type */
|
/* check whether if branch's stack matches its result type */
|
||||||
|
@ -6916,26 +6930,43 @@ re_scan:
|
||||||
goto fail;
|
goto fail;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Refer to a forward-declared function */
|
/* Refer to a forward-declared function:
|
||||||
if (func_idx >= cur_func_idx + module->import_function_count) {
|
the function must be an import, exported, or present in
|
||||||
|
a table elem segment or global initializer to be used as
|
||||||
|
the operand to ref.func */
|
||||||
|
if (func_idx >= module->import_function_count) {
|
||||||
WASMTableSeg *table_seg = module->table_segments;
|
WASMTableSeg *table_seg = module->table_segments;
|
||||||
bool func_declared = false;
|
bool func_declared = false;
|
||||||
uint32 j;
|
uint32 j;
|
||||||
|
|
||||||
/* Check whether the function is declared in table segs,
|
for (i = 0; i < module->global_count; i++) {
|
||||||
note that it doesn't matter whether the table seg's mode
|
if (module->globals[i].type == VALUE_TYPE_FUNCREF
|
||||||
is passive, active or declarative. */
|
&& module->globals[i].init_expr.init_expr_type
|
||||||
for (i = 0; i < module->table_seg_count; i++, table_seg++) {
|
== INIT_EXPR_TYPE_FUNCREF_CONST
|
||||||
if (table_seg->elem_type == VALUE_TYPE_FUNCREF) {
|
&& module->globals[i].init_expr.u.u32 == func_idx) {
|
||||||
for (j = 0; j < table_seg->value_count; j++) {
|
func_declared = true;
|
||||||
if (table_seg->init_values[j].u.ref_index
|
break;
|
||||||
== func_idx) {
|
}
|
||||||
func_declared = true;
|
}
|
||||||
break;
|
|
||||||
|
if (!func_declared) {
|
||||||
|
/* Check whether the function is declared in table segs,
|
||||||
|
note that it doesn't matter whether the table seg's
|
||||||
|
mode is passive, active or declarative. */
|
||||||
|
for (i = 0; i < module->table_seg_count;
|
||||||
|
i++, table_seg++) {
|
||||||
|
if (table_seg->elem_type == VALUE_TYPE_FUNCREF) {
|
||||||
|
for (j = 0; j < table_seg->value_count; j++) {
|
||||||
|
if (table_seg->init_values[j].u.ref_index
|
||||||
|
== func_idx) {
|
||||||
|
func_declared = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!func_declared) {
|
if (!func_declared) {
|
||||||
/* Check whether the function is exported */
|
/* Check whether the function is exported */
|
||||||
for (i = 0; i < module->export_count; i++) {
|
for (i = 0; i < module->export_count; i++) {
|
||||||
|
|
Loading…
Reference in New Issue
Block a user