Add checks to avoid wasm_runtime_malloc memory with size 0 (#507)
In some platforms, allocating memory with size 0 may return NULL but not an empty memory block, which causes runtime load, instantiate or execute wasm/aot file failed. We add checks to try to avoid allocating memory in runtime if the size is 0. And in wasm_runtime_malloc/free, output warning if allocate memory with size 0 and free memory with NULL ptr. Also fix some coding style issues, fix handle riscv32 ilp32d issue, and fix several wasm-c-api issues. Signed-off-by: Wenyong Huang <wenyong.huang@intel.com>
This commit is contained in:
@ -23,7 +23,7 @@ void
|
||||
wasm_instance_delete_internal(wasm_instance_t *);
|
||||
|
||||
static void *
|
||||
malloc_internal(size_t size)
|
||||
malloc_internal(uint64 size)
|
||||
{
|
||||
void *mem = NULL;
|
||||
|
||||
@ -47,8 +47,7 @@ malloc_internal(size_t size)
|
||||
/* Vectors */
|
||||
#define INIT_VEC(vector_p, func_prefix, size) \
|
||||
do { \
|
||||
vector_p = malloc_internal(sizeof(*(vector_p))); \
|
||||
if (!vector_p) { \
|
||||
if (!(vector_p = malloc_internal(sizeof(*(vector_p))))) { \
|
||||
goto failed; \
|
||||
} \
|
||||
func_prefix##_new_uninitialized(vector_p, size); \
|
||||
@ -75,7 +74,8 @@ malloc_internal(size_t size)
|
||||
static inline void
|
||||
generic_vec_init_data(Vector *out, size_t num_of_elems, size_t size_of_elem)
|
||||
{
|
||||
if (!bh_vector_init(out, num_of_elems, size_of_elem)) {
|
||||
/* size 0 is meaningless for a elemment */
|
||||
if (!size_of_elem || !bh_vector_init(out, num_of_elems, size_of_elem)) {
|
||||
out->data = NULL;
|
||||
out->max_elems = 0;
|
||||
out->num_elems = 0;
|
||||
@ -99,7 +99,7 @@ wasm_byte_vec_copy(wasm_byte_vec_t *out, const wasm_byte_vec_t *src)
|
||||
|
||||
bh_assert(out && src);
|
||||
|
||||
generic_vec_init_data((Vector *)out, src->size, src->size_of_elem);
|
||||
generic_vec_init_data((Vector *)out, src->size, sizeof(wasm_byte_t));
|
||||
if (!out->data) {
|
||||
goto failed;
|
||||
}
|
||||
@ -187,7 +187,7 @@ wasm_engine_new_internal(mem_alloc_type_t type,
|
||||
goto failed;
|
||||
}
|
||||
|
||||
#if BH_DEBUG == 1
|
||||
#if BH_DEBUG != 0
|
||||
bh_log_set_verbose_level(5);
|
||||
#else
|
||||
bh_log_set_verbose_level(3);
|
||||
@ -459,7 +459,7 @@ wasm_valtype_vec_copy(wasm_valtype_vec_t *out, const wasm_valtype_vec_t *src)
|
||||
|
||||
bh_assert(out && src);
|
||||
|
||||
generic_vec_init_data((Vector *)out, src->size, src->size_of_elem);
|
||||
generic_vec_init_data((Vector *)out, src->size, sizeof(wasm_valtype_t *));
|
||||
if (!out->data) {
|
||||
goto failed;
|
||||
}
|
||||
@ -1116,33 +1116,41 @@ failed:
|
||||
static void
|
||||
native_func_trampoline(wasm_exec_env_t exec_env, uint64 *argv)
|
||||
{
|
||||
wasm_val_t *params = NULL;
|
||||
wasm_val_t *results = NULL;
|
||||
wasm_val_t *params = NULL, *results = NULL;
|
||||
uint32 argc = 0;
|
||||
const wasm_func_t *func = NULL;
|
||||
wasm_trap_t *trap = NULL;
|
||||
|
||||
bh_assert(argv);
|
||||
size_t param_count, result_count;
|
||||
|
||||
func = wasm_runtime_get_function_attachment(exec_env);
|
||||
bh_assert(func);
|
||||
|
||||
params = malloc_internal(wasm_func_param_arity(func) * sizeof(wasm_val_t));
|
||||
if (!params) {
|
||||
goto failed;
|
||||
param_count = wasm_func_param_arity(func);
|
||||
if (param_count) {
|
||||
if (!argv) {
|
||||
goto failed;
|
||||
}
|
||||
|
||||
if (!(params = malloc_internal(param_count * sizeof(wasm_val_t)))) {
|
||||
goto failed;
|
||||
}
|
||||
|
||||
/* argv -> const wasm_val_t params[] */
|
||||
if (!(argc = argv_to_params(
|
||||
argv, wasm_functype_params(wasm_func_type(func)), params))) {
|
||||
goto failed;
|
||||
}
|
||||
}
|
||||
|
||||
results =
|
||||
malloc_internal(wasm_func_result_arity(func) * sizeof(wasm_val_t));
|
||||
if (!results) {
|
||||
goto failed;
|
||||
}
|
||||
result_count = wasm_func_result_arity(func);
|
||||
if (result_count) {
|
||||
if (!argv) {
|
||||
goto failed;
|
||||
}
|
||||
|
||||
/* argv -> const wasm_val_t params[] */
|
||||
argc =
|
||||
argv_to_params(argv, wasm_functype_params(wasm_func_type(func)), params);
|
||||
if (wasm_func_param_arity(func) && !argc) {
|
||||
goto failed;
|
||||
if (!(results = malloc_internal(result_count * sizeof(wasm_val_t)))) {
|
||||
goto failed;
|
||||
}
|
||||
}
|
||||
|
||||
if (func->with_env) {
|
||||
@ -1164,16 +1172,17 @@ native_func_trampoline(wasm_exec_env_t exec_env, uint64 *argv)
|
||||
}
|
||||
}
|
||||
|
||||
/* there is no result or there is an exception */
|
||||
if (trap || !wasm_func_result_arity(func)) {
|
||||
if (argv) {
|
||||
memset(argv, 0, wasm_func_param_arity(func) * sizeof(uint64));
|
||||
}
|
||||
|
||||
/* wasm_val_t results[] -> argv */
|
||||
argc = results_to_argv(results,
|
||||
wasm_functype_results(wasm_func_type(func)), argv);
|
||||
if (wasm_func_result_arity(func) && !argc) {
|
||||
goto failed;
|
||||
/* there is no trap and there is return values */
|
||||
if (!trap && result_count) {
|
||||
/* wasm_val_t results[] -> argv */
|
||||
if (!(argc = results_to_argv(
|
||||
results, wasm_functype_results(wasm_func_type(func)), argv))) {
|
||||
goto failed;
|
||||
}
|
||||
}
|
||||
|
||||
failed:
|
||||
@ -1503,8 +1512,7 @@ wasm_func_call(const wasm_func_t *func,
|
||||
/* a parameter list and a return value list */
|
||||
uint32 *argv = NULL;
|
||||
WASMFunctionInstanceCommon *func_comm_rt = NULL;
|
||||
size_t param_count = 0;
|
||||
size_t result_count = 0;
|
||||
size_t param_count, result_count, alloc_count;
|
||||
|
||||
bh_assert(func && func->func_type && func->inst_comm_rt);
|
||||
|
||||
@ -1527,17 +1535,18 @@ wasm_func_call(const wasm_func_t *func,
|
||||
|
||||
param_count = wasm_func_param_arity(func);
|
||||
result_count = wasm_func_result_arity(func);
|
||||
argv = malloc_internal(
|
||||
sizeof(uint64)
|
||||
* (param_count > result_count ? param_count : result_count));
|
||||
if (!argv) {
|
||||
goto failed;
|
||||
alloc_count = (param_count > result_count) ? param_count : result_count;
|
||||
if (alloc_count) {
|
||||
if (!(argv = malloc_internal(sizeof(uint64) * alloc_count))) {
|
||||
goto failed;
|
||||
}
|
||||
}
|
||||
|
||||
/* copy parametes */
|
||||
argc = params_to_argv(params, wasm_functype_params(wasm_func_type(func)),
|
||||
wasm_func_param_arity(func), argv);
|
||||
if (wasm_func_param_arity(func) && !argc) {
|
||||
if (param_count
|
||||
&& !(argc = params_to_argv(params,
|
||||
wasm_functype_params(wasm_func_type(func)),
|
||||
wasm_func_param_arity(func), argv))) {
|
||||
goto failed;
|
||||
}
|
||||
|
||||
@ -1548,9 +1557,10 @@ wasm_func_call(const wasm_func_t *func,
|
||||
}
|
||||
|
||||
/* copy results */
|
||||
argc = argv_to_results(argv, wasm_functype_results(wasm_func_type(func)),
|
||||
wasm_func_result_arity(func), results);
|
||||
if (wasm_func_result_arity(func) && !argc) {
|
||||
if (result_count
|
||||
&& !(argc = argv_to_results(
|
||||
argv, wasm_functype_results(wasm_func_type(func)),
|
||||
wasm_func_result_arity(func), results))) {
|
||||
goto failed;
|
||||
}
|
||||
|
||||
@ -2734,7 +2744,7 @@ wasm_extern_vec_copy(wasm_extern_vec_t *out, const wasm_extern_vec_t *src)
|
||||
size_t i = 0;
|
||||
bh_assert(out && src);
|
||||
|
||||
generic_vec_init_data((Vector *)out, src->size, src->size_of_elem);
|
||||
generic_vec_init_data((Vector *)out, src->size, sizeof(wasm_extern_t *));
|
||||
if (!out->data) {
|
||||
goto failed;
|
||||
}
|
||||
|
||||
@ -161,8 +161,14 @@ wasm_runtime_realloc_internal(void *ptr, unsigned int size)
|
||||
static inline void
|
||||
wasm_runtime_free_internal(void *ptr)
|
||||
{
|
||||
if (!ptr) {
|
||||
LOG_WARNING("warning: wasm_runtime_free with NULL pointer\n");
|
||||
return;
|
||||
}
|
||||
|
||||
if (memory_mode == MEMORY_MODE_UNKNOWN) {
|
||||
LOG_WARNING("wasm_runtime_free failed: memory hasn't been initialize.\n");
|
||||
LOG_WARNING("warning: wasm_runtime_free failed: "
|
||||
"memory hasn't been initialize.\n");
|
||||
}
|
||||
else if (memory_mode == MEMORY_MODE_POOL) {
|
||||
mem_allocator_free(pool_allocator, ptr);
|
||||
@ -175,6 +181,12 @@ wasm_runtime_free_internal(void *ptr)
|
||||
void *
|
||||
wasm_runtime_malloc(unsigned int size)
|
||||
{
|
||||
if (size == 0) {
|
||||
LOG_WARNING("warning: wasm_runtime_malloc with size zero\n");
|
||||
/* At lease alloc 1 byte to avoid malloc failed */
|
||||
size = 1;
|
||||
}
|
||||
|
||||
return wasm_runtime_malloc_internal(size);
|
||||
}
|
||||
|
||||
|
||||
@ -1712,9 +1712,11 @@ wasm_runtime_init_wasi(WASMModuleInstanceCommon *module_inst,
|
||||
|
||||
total_size = sizeof(char *) * (uint64)argc;
|
||||
if (total_size >= UINT32_MAX
|
||||
|| !(argv_list = wasm_runtime_malloc((uint32)total_size))
|
||||
|| (total_size > 0 &&
|
||||
!(argv_list = wasm_runtime_malloc((uint32)total_size)))
|
||||
|| argv_buf_size >= UINT32_MAX
|
||||
|| !(argv_buf = wasm_runtime_malloc((uint32)argv_buf_size))) {
|
||||
|| (argv_buf_size > 0 &&
|
||||
!(argv_buf = wasm_runtime_malloc((uint32)argv_buf_size)))) {
|
||||
set_error_buf(error_buf, error_buf_size,
|
||||
"Init wasi environment failed: allocate memory failed");
|
||||
goto fail;
|
||||
@ -1730,11 +1732,13 @@ wasm_runtime_init_wasi(WASMModuleInstanceCommon *module_inst,
|
||||
for (i = 0; i < env_count; i++)
|
||||
env_buf_size += strlen(env[i]) + 1;
|
||||
|
||||
total_size = sizeof(char *) * (uint64)argc;
|
||||
total_size = sizeof(char *) * (uint64)env_count;
|
||||
if (total_size >= UINT32_MAX
|
||||
|| !(env_list = wasm_runtime_malloc((uint32)total_size))
|
||||
|| (total_size > 0
|
||||
&& !(env_list = wasm_runtime_malloc((uint32)total_size)))
|
||||
|| env_buf_size >= UINT32_MAX
|
||||
|| !(env_buf = wasm_runtime_malloc((uint32)env_buf_size))) {
|
||||
|| (env_buf_size > 0
|
||||
&& !(env_buf = wasm_runtime_malloc((uint32)env_buf_size)))) {
|
||||
set_error_buf(error_buf, error_buf_size,
|
||||
"Init wasi environment failed: allocate memory failed");
|
||||
goto fail;
|
||||
@ -2842,6 +2846,7 @@ wasm_runtime_invoke_native(WASMExecEnv *exec_env, void *func_ptr,
|
||||
n_stacks++;
|
||||
n_stacks += 2;
|
||||
}
|
||||
break;
|
||||
#endif /* BUILD_TARGET_RISCV32_ILP32D */
|
||||
default:
|
||||
bh_assert(0);
|
||||
|
||||
Reference in New Issue
Block a user