Skip to content

Commit bf2be80

Browse files
authored
Add more checks about the imports of wasm_instance_new (#1843)
Check whether the `imports` argument is NULL in wasm_instance_new and check the import count of each kind. Fix issue reported by #1833
1 parent d5aa354 commit bf2be80

File tree

3 files changed

+102
-63
lines changed

3 files changed

+102
-63
lines changed

core/iwasm/common/wasm_c_api.c

Lines changed: 90 additions & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
* SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
44
*/
55

6+
#include "bh_log.h"
67
#include "wasm_c_api_internal.h"
78

89
#include "bh_assert.h"
@@ -275,10 +276,14 @@ WASM_DEFINE_VEC_OWN(store, wasm_store_delete)
275276
WASM_DEFINE_VEC_OWN(valtype, wasm_valtype_delete)
276277

277278
#ifndef NDEBUG
279+
#if WAMR_BUILD_MEMORY_PROFILING != 0
278280
#define WASM_C_DUMP_PROC_MEM() LOG_PROC_MEM()
279281
#else
280282
#define WASM_C_DUMP_PROC_MEM() (void)0
281283
#endif
284+
#else
285+
#define WASM_C_DUMP_PROC_MEM() (void)0
286+
#endif
282287

283288
/* Runtime Environment */
284289
own wasm_config_t *
@@ -4345,7 +4350,7 @@ interp_link_global(const WASMModule *module_interp, uint16 global_idx_rt,
43454350
return true;
43464351
}
43474352

4348-
static uint32
4353+
static bool
43494354
interp_link(const wasm_instance_t *inst, const WASMModule *module_interp,
43504355
wasm_extern_t *imports[])
43514356
{
@@ -4390,11 +4395,11 @@ interp_link(const wasm_instance_t *inst, const WASMModule *module_interp,
43904395
}
43914396
}
43924397

4393-
return i;
4398+
return true;
43944399

43954400
failed:
43964401
LOG_DEBUG("%s failed", __FUNCTION__);
4397-
return (uint32)-1;
4402+
return false;
43984403
}
43994404

44004405
static bool
@@ -4557,7 +4562,7 @@ aot_link_global(const AOTModule *module_aot, uint16 global_idx_rt,
45574562
return false;
45584563
}
45594564

4560-
static uint32
4565+
static bool
45614566
aot_link(const wasm_instance_t *inst, const AOTModule *module_aot,
45624567
wasm_extern_t *imports[])
45634568
{
@@ -4605,11 +4610,11 @@ aot_link(const wasm_instance_t *inst, const AOTModule *module_aot,
46054610
}
46064611
}
46074612

4608-
return i;
4613+
return true;
46094614

46104615
failed:
46114616
LOG_DEBUG("%s failed", __FUNCTION__);
4612-
return (uint32)-1;
4617+
return false;
46134618
}
46144619

46154620
static bool
@@ -4713,6 +4718,57 @@ wasm_instance_new(wasm_store_t *store, const wasm_module_t *module,
47134718
KILOBYTE(32), KILOBYTE(32));
47144719
}
47154720

4721+
static bool
4722+
compare_imports(const wasm_module_t *module, const wasm_extern_vec_t *imports)
4723+
{
4724+
unsigned import_func_count = 0;
4725+
unsigned import_global_count = 0;
4726+
unsigned import_memory_count = 0;
4727+
unsigned import_table_count = 0;
4728+
unsigned i = 0;
4729+
4730+
for (i = 0; imports && i < imports->num_elems; i++) {
4731+
wasm_extern_t *import = imports->data[i];
4732+
switch (wasm_extern_kind(import)) {
4733+
case WASM_EXTERN_FUNC:
4734+
import_func_count++;
4735+
break;
4736+
case WASM_EXTERN_GLOBAL:
4737+
import_global_count++;
4738+
break;
4739+
case WASM_EXTERN_MEMORY:
4740+
import_memory_count++;
4741+
break;
4742+
case WASM_EXTERN_TABLE:
4743+
import_table_count++;
4744+
break;
4745+
default:
4746+
UNREACHABLE();
4747+
return false;
4748+
}
4749+
}
4750+
4751+
#if WASM_ENABLE_INTERP != 0
4752+
if ((*module)->module_type == Wasm_Module_Bytecode)
4753+
return import_func_count == MODULE_INTERP(module)->import_function_count
4754+
&& import_global_count
4755+
== MODULE_INTERP(module)->import_global_count
4756+
&& import_memory_count
4757+
== MODULE_INTERP(module)->import_memory_count
4758+
&& import_table_count
4759+
== MODULE_INTERP(module)->import_table_count;
4760+
#endif
4761+
#if WASM_ENABLE_AOT != 0
4762+
if ((*module)->module_type == Wasm_Module_AoT)
4763+
return import_func_count == MODULE_AOT(module)->import_func_count
4764+
&& import_global_count == MODULE_AOT(module)->import_global_count
4765+
&& import_memory_count == MODULE_AOT(module)->import_memory_count
4766+
&& import_table_count == MODULE_AOT(module)->import_table_count;
4767+
#endif
4768+
4769+
return false;
4770+
}
4771+
47164772
wasm_instance_t *
47174773
wasm_instance_new_with_args(wasm_store_t *store, const wasm_module_t *module,
47184774
const wasm_extern_vec_t *imports,
@@ -4721,18 +4777,22 @@ wasm_instance_new_with_args(wasm_store_t *store, const wasm_module_t *module,
47214777
{
47224778
char sub_error_buf[128] = { 0 };
47234779
char error_buf[256] = { 0 };
4724-
bool import_count_verified = false;
47254780
wasm_instance_t *instance = NULL;
47264781
WASMModuleInstance *inst_rt;
47274782
CApiFuncImport *func_import = NULL, **p_func_imports = NULL;
4728-
uint32 i = 0, import_count = 0, import_func_count = 0;
4783+
uint32 i = 0, import_func_count = 0;
47294784
uint64 total_size;
4730-
bool processed = false;
4785+
bool build_exported = false;
47314786

47324787
bh_assert(singleton_engine);
47334788

4734-
if (!module) {
4789+
if (!module)
47354790
return NULL;
4791+
4792+
if (!compare_imports(module, imports)) {
4793+
snprintf(sub_error_buf, sizeof(sub_error_buf),
4794+
"Failed to match imports");
4795+
goto failed;
47364796
}
47374797

47384798
WASM_C_DUMP_PROC_MEM();
@@ -4746,51 +4806,36 @@ wasm_instance_new_with_args(wasm_store_t *store, const wasm_module_t *module,
47464806

47474807
/* link module and imports */
47484808
if (imports && imports->num_elems) {
4809+
bool link = false;
47494810
#if WASM_ENABLE_INTERP != 0
47504811
if ((*module)->module_type == Wasm_Module_Bytecode) {
4751-
import_count = MODULE_INTERP(module)->import_count;
4752-
4753-
if (import_count) {
4754-
uint32 actual_link_import_count =
4755-
interp_link(instance, MODULE_INTERP(module),
4756-
(wasm_extern_t **)imports->data);
4757-
/* make sure a complete import list */
4758-
if ((int32)import_count < 0
4759-
|| import_count != actual_link_import_count) {
4760-
snprintf(sub_error_buf, sizeof(sub_error_buf),
4761-
"Failed to validate imports");
4762-
goto failed;
4763-
}
4812+
if (!interp_link(instance, MODULE_INTERP(module),
4813+
(wasm_extern_t **)imports->data)) {
4814+
snprintf(sub_error_buf, sizeof(sub_error_buf),
4815+
"Failed to validate imports");
4816+
goto failed;
47644817
}
4765-
import_count_verified = true;
4818+
link = true;
47664819
}
47674820
#endif
47684821

47694822
#if WASM_ENABLE_AOT != 0
47704823
if ((*module)->module_type == Wasm_Module_AoT) {
4771-
import_count = MODULE_AOT(module)->import_func_count
4772-
+ MODULE_AOT(module)->import_global_count
4773-
+ MODULE_AOT(module)->import_memory_count
4774-
+ MODULE_AOT(module)->import_table_count;
4775-
4776-
if (import_count) {
4777-
import_count = aot_link(instance, MODULE_AOT(module),
4778-
(wasm_extern_t **)imports->data);
4779-
if ((int32)import_count < 0) {
4780-
snprintf(sub_error_buf, sizeof(sub_error_buf),
4781-
"Failed to validate imports");
4782-
goto failed;
4783-
}
4824+
if (!aot_link(instance, MODULE_AOT(module),
4825+
(wasm_extern_t **)imports->data)) {
4826+
snprintf(sub_error_buf, sizeof(sub_error_buf),
4827+
"Failed to validate imports");
4828+
goto failed;
47844829
}
4785-
import_count_verified = true;
4830+
link = true;
47864831
}
47874832
#endif
47884833

47894834
/*
47904835
* a wrong combination of module filetype and compilation flags
47914836
* also leads to below branch
47924837
*/
4793-
if (!import_count_verified) {
4838+
if (!link) {
47944839
snprintf(sub_error_buf, sizeof(sub_error_buf),
47954840
"Failed to verify import count");
47964841
goto failed;
@@ -4809,6 +4854,7 @@ wasm_instance_new_with_args(wasm_store_t *store, const wasm_module_t *module,
48094854
goto failed;
48104855
}
48114856

4857+
/* create the c-api func import list */
48124858
inst_rt = (WASMModuleInstance *)instance->inst_comm_rt;
48134859
#if WASM_ENABLE_INTERP != 0
48144860
if (instance->inst_comm_rt->module_type == Wasm_Module_Bytecode) {
@@ -4825,7 +4871,6 @@ wasm_instance_new_with_args(wasm_store_t *store, const wasm_module_t *module,
48254871
#endif
48264872
bh_assert(p_func_imports);
48274873

4828-
/* create the c-api func import list */
48294874
total_size = (uint64)sizeof(CApiFuncImport) * import_func_count;
48304875
if (total_size > 0
48314876
&& !(*p_func_imports = func_import = malloc_internal(total_size))) {
@@ -4835,7 +4880,7 @@ wasm_instance_new_with_args(wasm_store_t *store, const wasm_module_t *module,
48354880
}
48364881

48374882
/* fill in c-api func import list */
4838-
for (i = 0; i < import_count; i++) {
4883+
for (i = 0; imports && i < imports->num_elems; i++) {
48394884
wasm_func_t *func_host;
48404885
wasm_extern_t *in;
48414886

@@ -4857,10 +4902,9 @@ wasm_instance_new_with_args(wasm_store_t *store, const wasm_module_t *module,
48574902

48584903
func_import++;
48594904
}
4860-
bh_assert((uint32)(func_import - *p_func_imports) == import_func_count);
48614905

48624906
/* fill with inst */
4863-
for (i = 0; imports && imports->data && i < (uint32)import_count; ++i) {
4907+
for (i = 0; imports && imports->data && i < imports->num_elems; ++i) {
48644908
wasm_extern_t *import = imports->data[i];
48654909
switch (import->kind) {
48664910
case WASM_EXTERN_FUNC:
@@ -4903,7 +4947,7 @@ wasm_instance_new_with_args(wasm_store_t *store, const wasm_module_t *module,
49034947
goto failed;
49044948
}
49054949

4906-
processed = true;
4950+
build_exported = true;
49074951
}
49084952
#endif
49094953

@@ -4927,15 +4971,15 @@ wasm_instance_new_with_args(wasm_store_t *store, const wasm_module_t *module,
49274971
goto failed;
49284972
}
49294973

4930-
processed = true;
4974+
build_exported = true;
49314975
}
49324976
#endif
49334977

49344978
/*
49354979
* a wrong combination of module filetype and compilation flags
49364980
* leads to below branch
49374981
*/
4938-
if (!processed) {
4982+
if (!build_exported) {
49394983
snprintf(sub_error_buf, sizeof(sub_error_buf),
49404984
"Incorrect filetype and compilation flags");
49414985
goto failed;

samples/wasm-c-api/CMakeLists.txt

Lines changed: 11 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -159,6 +159,9 @@ endif()
159159

160160
check_pie_supported()
161161

162+
include(CTest)
163+
enable_testing()
164+
162165
foreach(EX ${EXAMPLES})
163166
set(SRC ${CMAKE_CURRENT_LIST_DIR}/src/${EX}.c)
164167

@@ -193,6 +196,12 @@ foreach(EX ${EXAMPLES})
193196
)
194197
add_dependencies(${EX} ${EX}_AOT)
195198
endif()
199+
200+
# run `ctest --test-dir build`
201+
add_test(NAME Test_${EX}
202+
COMMAND ./${EX}
203+
WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}
204+
)
196205
endforeach()
197206

198207
if (CMAKE_BUILD_TYPE STREQUAL "Debug")
@@ -201,19 +210,5 @@ if (CMAKE_BUILD_TYPE STREQUAL "Debug")
201210
REQUIRED
202211
)
203212

204-
if(VALGRIND)
205-
foreach(EX ${EXAMPLES})
206-
add_custom_command(
207-
OUTPUT ${EX}_leak_check.report
208-
DEPENDS ${EX} ${EX}_WASM
209-
COMMAND ${VALGRIND} --tool=memcheck --leak-check=full -- ./${EX} > ${EX}_leak_check.report 2>&1
210-
WORKING_DIRECTORY ${CMAKE_BINARY_DIR}
211-
)
212-
add_custom_target(${EX}_LEAK_TEST ALL
213-
DEPENDS ${EX}_leak_check.report
214-
COMMAND grep "All heap blocks were freed -- no leaks are possible" ${EX}_leak_check.report
215-
COMMENT "Please read ${EX}_leak_check.report when meeting Error"
216-
)
217-
endforeach()
218-
endif (VALGRIND)
219-
endif (CMAKE_BUILD_TYPE STREQUAL "Debug")
213+
# run `ctest -T memcheck -V --test-dir build`
214+
endif()

samples/wasm-c-api/src/callback_chain.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -238,7 +238,7 @@ main(int argc, const char *argv[])
238238
IMPORT_FUNCTION_LIST(CREATE_WASM_FUNCTION)
239239
#undef CREATE_WASM_FUNCTION
240240

241-
wasm_extern_t *fs[10] = { 0 };
241+
wasm_extern_t *fs[2] = { 0 };
242242
#define ADD_TO_FUNCTION_LIST(name, index, ...) \
243243
fs[index] = wasm_func_as_extern(function_##name);
244244
IMPORT_FUNCTION_LIST(ADD_TO_FUNCTION_LIST)

0 commit comments

Comments
 (0)