Skip to content

Commit

Permalink
Fix ref.func forward-declared function check (bytecodealliance#2099)
Browse files Browse the repository at this point in the history
When ref.func opcode refers to a function whose function index no smaller than
current function, the destination func should be forward-declared: it is declared
in the table element segments, or is declared in the export list.
  • Loading branch information
wenyongh committed Apr 3, 2023
1 parent 6ffc17a commit 2814739
Show file tree
Hide file tree
Showing 2 changed files with 27 additions and 7 deletions.
16 changes: 14 additions & 2 deletions core/iwasm/interpreter/wasm_loader.c
Original file line number Diff line number Diff line change
Expand Up @@ -8222,12 +8222,13 @@ wasm_loader_prepare_bytecode(WASMModule *module, WASMFunction *func,
goto fail;
}

if (func_idx == cur_func_idx + module->import_function_count) {
/* Refer to a forward-declared function */
if (func_idx >= cur_func_idx + module->import_function_count) {
WASMTableSeg *table_seg = module->table_segments;
bool func_declared = false;
uint32 j;

/* Check whether current function is declared */
/* Check whether the function is declared in table segs */
for (i = 0; i < module->table_seg_count; i++, table_seg++) {
if (table_seg->elem_type == VALUE_TYPE_FUNCREF
&& wasm_elem_is_declarative(table_seg->mode)) {
Expand All @@ -8239,6 +8240,17 @@ wasm_loader_prepare_bytecode(WASMModule *module, WASMFunction *func,
}
}
}
if (!func_declared) {
/* Check whether the function is exported */
for (i = 0; i < module->export_count; i++) {
if (module->exports[i].kind == EXPORT_KIND_FUNC
&& module->exports[i].index == func_idx) {
func_declared = true;
break;
}
}
}

if (!func_declared) {
set_error_buf(error_buf, error_buf_size,
"undeclared function reference");
Expand Down
18 changes: 13 additions & 5 deletions core/iwasm/interpreter/wasm_mini_loader.c
Original file line number Diff line number Diff line change
Expand Up @@ -6384,12 +6384,13 @@ wasm_loader_prepare_bytecode(WASMModule *module, WASMFunction *func,
goto fail;
}

if (func_idx == cur_func_idx + module->import_function_count) {
/* Refer to a forward-declared function */
if (func_idx >= cur_func_idx + module->import_function_count) {
WASMTableSeg *table_seg = module->table_segments;
bool func_declared = false;
uint32 j;

/* Check whether current function is declared */
/* Check whether the function is declared in table segs */
for (i = 0; i < module->table_seg_count; i++, table_seg++) {
if (table_seg->elem_type == VALUE_TYPE_FUNCREF
&& wasm_elem_is_declarative(table_seg->mode)) {
Expand All @@ -6402,10 +6403,17 @@ wasm_loader_prepare_bytecode(WASMModule *module, WASMFunction *func,
}
}
if (!func_declared) {
set_error_buf(error_buf, error_buf_size,
"undeclared function reference");
goto fail;
/* Check whether the function is exported */
for (i = 0; i < module->export_count; i++) {
if (module->exports[i].kind == EXPORT_KIND_FUNC
&& module->exports[i].index == func_idx) {
func_declared = true;
break;
}
}
}
bh_assert(func_declared);
(void)func_declared;
}

#if WASM_ENABLE_FAST_INTERP != 0
Expand Down

0 comments on commit 2814739

Please sign in to comment.