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:
Wenyong Huang
2021-01-28 02:16:02 -06:00
committed by GitHub
parent efd648959c
commit a5188f5574
20 changed files with 240 additions and 131 deletions

View File

@ -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;
}

View File

@ -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);
}

View File

@ -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);