Add more checks to enhance security (#446)

add more checks to enhance security
clear "wasi proc exit" exception before return to caller in wasm/aot call functions
fix memory profiling issue
change movdqa to movdqu in simd invokeNative asm codes to fix issue of unaligned address access
move setjmp/longjmp from libc-builtin to libc-emcc
fix zephyr platform compilation issue in latest zephyr version
This commit is contained in:
Wenyong Huang
2020-11-24 14:00:09 +08:00
committed by GitHub
parent f4770ae8c8
commit 74be7a0b7c
24 changed files with 397 additions and 216 deletions

View File

@ -343,26 +343,22 @@ memories_instantiate(const WASMModule *module,
uint32 actual_heap_size = heap_size;
#if WASM_ENABLE_MULTI_MODULE != 0
WASMMemoryInstance *memory_inst_linked = NULL;
if (import->u.memory.import_module != NULL) {
WASMModuleInstance *module_inst_linked;
LOG_DEBUG("(%s, %s) is a memory of a sub-module",
import->u.memory.module_name,
import->u.memory.field_name);
if (!(module_inst_linked = get_sub_module_inst(
module_inst, import->u.memory.import_module))) {
set_error_buf(error_buf, error_buf_size, "unknown memory");
memories_deinstantiate(module_inst, memories, memory_count);
return NULL;
}
module_inst_linked =
get_sub_module_inst(module_inst,
import->u.memory.import_module);
bh_assert(module_inst_linked);
memory_inst_linked =
wasm_lookup_memory(module_inst_linked,
import->u.memory.field_name);
bh_assert(memory_inst_linked);
memories[mem_index++] = memory_inst_linked;
memory = memory_inst_linked;
if (!(memory = memories[mem_index++] = wasm_lookup_memory(
module_inst_linked, import->u.memory.field_name))) {
set_error_buf(error_buf, error_buf_size, "unknown memory");
memories_deinstantiate(module_inst, memories, memory_count);
return NULL;
}
}
else
#endif
@ -374,6 +370,13 @@ memories_instantiate(const WASMModule *module,
memories_deinstantiate(module_inst, memories, memory_count);
return NULL;
}
#if WASM_ENABLE_MULTI_MODULE != 0
/* The module of the import memory is a builtin module, and
the memory is created by current module, set its owner
to current module, so the memory can be destroyed in
memories_deinstantiate. */
memory->owner = module_inst;
#endif
}
}
@ -453,17 +456,19 @@ tables_instantiate(const WASMModule *module,
WASMTableInstance *table_inst_linked = NULL;
WASMModuleInstance *module_inst_linked = NULL;
if (import->u.table.import_module) {
LOG_DEBUG("(%s, %s) is a table of a sub-module",
import->u.table.module_name,
import->u.memory.field_name);
if (!(module_inst_linked =
get_sub_module_inst(module_inst, import->u.table.import_module))) {
set_error_buf(error_buf, error_buf_size, "unknown table");
tables_deinstantiate(tables, table_count);
return NULL;
}
module_inst_linked =
get_sub_module_inst(module_inst, import->u.table.import_module);
bh_assert(module_inst_linked);
table_inst_linked = wasm_lookup_table(module_inst_linked,
import->u.table.field_name);
bh_assert(table_inst_linked);
if (!(table_inst_linked = wasm_lookup_table(module_inst_linked,
import->u.table.field_name))) {
set_error_buf(error_buf, error_buf_size, "unknown table");
tables_deinstantiate(tables, table_count);
return NULL;
}
total_size = offsetof(WASMTableInstance, base_addr);
}
@ -692,16 +697,17 @@ globals_instantiate(const WASMModule *module,
global->is_mutable = global_import->is_mutable;
#if WASM_ENABLE_MULTI_MODULE != 0
if (global_import->import_module) {
WASMModuleInstance *sub_module_inst = get_sub_module_inst(
module_inst, global_import->import_module);
bh_assert(sub_module_inst);
if (!(global->import_module_inst = get_sub_module_inst(
module_inst, global_import->import_module))) {
set_error_buf(error_buf, error_buf_size, "unknown global");
return NULL;
}
WASMGlobalInstance *global_inst_linked =
wasm_lookup_global(sub_module_inst, global_import->field_name);
bh_assert(global_inst_linked);
global->import_global_inst = global_inst_linked;
global->import_module_inst = sub_module_inst;
if (!(global->import_global_inst = wasm_lookup_global(
global->import_module_inst, global_import->field_name))) {
set_error_buf(error_buf, error_buf_size, "unknown global");
return NULL;
}
/**
* although, actually don't need initial_value for an imported
@ -709,15 +715,11 @@ globals_instantiate(const WASMModule *module,
* global-data and
* (global $g2 i32 (global.get $g1))
*/
WASMGlobal *linked_global = global_import->import_global_linked;
InitializerExpression *linked_init_expr =
&(linked_global->init_expr);
bool ret = parse_init_expr(
linked_init_expr,
sub_module_inst->globals,
sub_module_inst->global_count, &(global->initial_value));
if (!ret) {
if (!parse_init_expr(
&(global_import->import_global_linked->init_expr),
global->import_module_inst->globals,
global->import_module_inst->global_count,
&(global->initial_value))) {
set_error_buf(error_buf, error_buf_size, "unknown global");
return NULL;
}
@ -1047,6 +1049,7 @@ sub_module_deinstantiate(WASMModuleInstance *module_inst)
WASMSubModInstNode *next_node = bh_list_elem_next(node);
bh_list_remove(list, node);
wasm_deinstantiate(node->module_inst, false);
wasm_runtime_free(node);
node = next_node;
}
}
@ -1143,8 +1146,7 @@ wasm_instantiate(WASMModule *module, bool is_sub_inst,
error_buf, error_buf_size);
if (!ret) {
LOG_DEBUG("build a sub module list failed");
wasm_deinstantiate(module_inst, false);
return NULL;
goto fail;
}
#endif
@ -1154,8 +1156,7 @@ wasm_instantiate(WASMModule *module, bool is_sub_inst,
&& !(globals = globals_instantiate(module, module_inst,
&global_data_size,
error_buf, error_buf_size))) {
wasm_deinstantiate(module_inst, false);
return NULL;
goto fail;
}
module_inst->global_count = global_count;
module_inst->globals = globals;
@ -1178,8 +1179,7 @@ wasm_instantiate(WASMModule *module, bool is_sub_inst,
if (global_count > 0) {
if (!(module_inst->global_data = runtime_malloc
(global_data_size, error_buf, error_buf_size))) {
wasm_deinstantiate(module_inst, false);
return NULL;
goto fail;
}
}
@ -1210,8 +1210,7 @@ wasm_instantiate(WASMModule *module, bool is_sub_inst,
error_buf, error_buf_size)))
#endif
) {
wasm_deinstantiate(module_inst, false);
return NULL;
goto fail;
}
if (global_count > 0) {
@ -1221,8 +1220,7 @@ wasm_instantiate(WASMModule *module, bool is_sub_inst,
*/
if (!globals_instantiate_fix(globals, module,
error_buf, error_buf_size)) {
wasm_deinstantiate(module_inst, false);
return NULL;
goto fail;
}
/* Initialize the global data */
@ -1250,8 +1248,7 @@ wasm_instantiate(WASMModule *module, bool is_sub_inst,
}
if (!check_linked_symbol(module_inst, error_buf, error_buf_size)) {
wasm_deinstantiate(module_inst, false);
return NULL;
goto fail;
}
/* Initialize the memory data with data segment section */
@ -1285,9 +1282,14 @@ wasm_instantiate(WASMModule *module, bool is_sub_inst,
if (data_seg->base_offset.init_expr_type
== INIT_EXPR_TYPE_GET_GLOBAL) {
bh_assert(data_seg->base_offset.u.global_index < global_count
&& globals[data_seg->base_offset.u.global_index].type
== VALUE_TYPE_I32);
if (!globals
|| data_seg->base_offset.u.global_index >= global_count
|| globals[data_seg->base_offset.u.global_index].type
!= VALUE_TYPE_I32) {
set_error_buf(error_buf, error_buf_size,
"data segment does not fit");
goto fail;
}
data_seg->base_offset.u.i32 =
globals[data_seg->base_offset.u.global_index]
.initial_value.i32;
@ -1300,8 +1302,7 @@ wasm_instantiate(WASMModule *module, bool is_sub_inst,
memory_size);
set_error_buf(error_buf, error_buf_size,
"data segment does not fit");
wasm_deinstantiate(module_inst, false);
return NULL;
goto fail;
}
/* check offset + length(could be zero) */
@ -1311,8 +1312,7 @@ wasm_instantiate(WASMModule *module, bool is_sub_inst,
base_offset, length, memory_size);
set_error_buf(error_buf, error_buf_size,
"data segment does not fit");
wasm_deinstantiate(module_inst, false);
return NULL;
goto fail;
}
bh_memcpy_s(memory_data + base_offset, memory_size - base_offset,
@ -1344,9 +1344,14 @@ wasm_instantiate(WASMModule *module, bool is_sub_inst,
if (table_seg->base_offset.init_expr_type
== INIT_EXPR_TYPE_GET_GLOBAL) {
bh_assert(table_seg->base_offset.u.global_index < global_count
&& globals[table_seg->base_offset.u.global_index].type
== VALUE_TYPE_I32);
if (!globals
|| table_seg->base_offset.u.global_index >= global_count
|| globals[table_seg->base_offset.u.global_index].type
!= VALUE_TYPE_I32) {
set_error_buf(error_buf, error_buf_size,
"elements segment does not fit");
goto fail;
}
table_seg->base_offset.u.i32 =
globals[table_seg->base_offset.u.global_index].initial_value.i32;
}
@ -1357,8 +1362,7 @@ wasm_instantiate(WASMModule *module, bool is_sub_inst,
table_seg->base_offset.u.i32, table->cur_size);
set_error_buf(error_buf, error_buf_size,
"elements segment does not fit");
wasm_deinstantiate(module_inst, false);
return NULL;
goto fail;
}
/* check offset + length(could be zero) */
@ -1368,8 +1372,7 @@ wasm_instantiate(WASMModule *module, bool is_sub_inst,
table_seg->base_offset.u.i32, length, table->cur_size);
set_error_buf(error_buf, error_buf_size,
"elements segment does not fit");
wasm_deinstantiate(module_inst, false);
return NULL;
goto fail;
}
/**
@ -1420,8 +1423,7 @@ wasm_instantiate(WASMModule *module, bool is_sub_inst,
module->wasi_args.argv,
module->wasi_args.argc,
error_buf, error_buf_size)) {
wasm_deinstantiate(module_inst, false);
return NULL;
goto fail;
}
}
#endif
@ -1438,8 +1440,7 @@ wasm_instantiate(WASMModule *module, bool is_sub_inst,
|| !execute_start_function(module_inst)) {
set_error_buf(error_buf, error_buf_size,
module_inst->cur_exception);
wasm_deinstantiate(module_inst, false);
return NULL;
goto fail;
}
#if WASM_ENABLE_BULK_MEMORY != 0
@ -1453,8 +1454,7 @@ wasm_instantiate(WASMModule *module, bool is_sub_inst,
if (!execute_memory_init_function(module_inst)) {
set_error_buf(error_buf, error_buf_size,
module_inst->cur_exception);
wasm_deinstantiate(module_inst, false);
return NULL;
goto fail;
}
}
#if WASM_ENABLE_LIBC_WASI != 0
@ -1468,6 +1468,9 @@ wasm_instantiate(WASMModule *module, bool is_sub_inst,
#endif
(void)global_data_end;
return module_inst;
fail:
wasm_deinstantiate(module_inst, false);
return NULL;
}
void
@ -1555,6 +1558,24 @@ wasm_lookup_table(const WASMModuleInstance *module_inst, const char *name)
}
#endif
static bool
clear_wasi_proc_exit_exception(WASMModuleInstance *module_inst)
{
#if WASM_ENABLE_LIBC_WASI != 0
const char *exception = wasm_get_exception(module_inst);
if (exception && !strcmp(exception, "Exception: wasi proc exit")) {
/* The "wasi proc exit" exception is thrown by native lib to
let wasm app exit, which is a normal behavior, we clear
the exception here. */
wasm_set_exception(module_inst, NULL);
return true;
}
return false;
#else
return false;
#endif
}
bool
wasm_call_function(WASMExecEnv *exec_env,
WASMFunctionInstance *function,
@ -1562,6 +1583,7 @@ wasm_call_function(WASMExecEnv *exec_env,
{
WASMModuleInstance *module_inst = (WASMModuleInstance*)exec_env->module_inst;
wasm_interp_call_wasm(module_inst, exec_env, function, argc, argv);
(void)clear_wasi_proc_exit_exception(module_inst);
return !wasm_get_exception(module_inst) ? true : false;
}
@ -1696,8 +1718,13 @@ wasm_validate_app_addr(WASMModuleInstance *module_inst,
uint32 app_offset, uint32 size)
{
WASMMemoryInstance *memory = module_inst->default_memory;
uint32 memory_data_size =
memory->num_bytes_per_page * memory->cur_page_count;
uint32 memory_data_size;
if (!memory) {
goto fail;
}
memory_data_size = memory->num_bytes_per_page * memory->cur_page_count;
/* integer overflow check */
if (app_offset + size < app_offset) {
@ -1716,8 +1743,12 @@ bool
wasm_validate_native_addr(WASMModuleInstance *module_inst,
void *native_ptr, uint32 size)
{
uint8 *addr = (uint8 *)native_ptr;
WASMMemoryInstance *memory = module_inst->default_memory;
uint8 *addr = (uint8 *)native_ptr;
if (!memory) {
goto fail;
}
/* integer overflow check */
if (addr + size < addr) {
@ -1738,7 +1769,12 @@ wasm_addr_app_to_native(WASMModuleInstance *module_inst,
uint32 app_offset)
{
WASMMemoryInstance *memory = module_inst->default_memory;
uint8 *addr = memory->memory_data + app_offset;
uint8 *addr;
if (!memory)
return NULL;
addr = memory->memory_data + app_offset;
if (memory->memory_data <= addr
&& addr < memory->memory_data_end)
@ -1753,6 +1789,9 @@ wasm_addr_native_to_app(WASMModuleInstance *module_inst,
WASMMemoryInstance *memory = module_inst->default_memory;
uint8 *addr = (uint8 *)native_ptr;
if (!memory)
return 0;
if (memory->memory_data <= addr
&& addr < memory->memory_data_end)
return (uint32)(addr - memory->memory_data);
@ -1766,8 +1805,12 @@ wasm_get_app_addr_range(WASMModuleInstance *module_inst,
uint32 *p_app_end_offset)
{
WASMMemoryInstance *memory = module_inst->default_memory;
uint32 memory_data_size =
memory->num_bytes_per_page * memory->cur_page_count;
uint32 memory_data_size;
if (!memory)
return false;
memory_data_size = memory->num_bytes_per_page * memory->cur_page_count;
if (app_offset < memory_data_size) {
if (p_app_start_offset)
@ -1788,6 +1831,9 @@ wasm_get_native_addr_range(WASMModuleInstance *module_inst,
WASMMemoryInstance *memory = module_inst->default_memory;
uint8 *addr = (uint8 *)native_ptr;
if (!memory)
return false;
if (memory->memory_data <= addr
&& addr < memory->memory_data_end) {
if (p_native_start_addr)
@ -1803,12 +1849,19 @@ bool
wasm_enlarge_memory(WASMModuleInstance *module, uint32 inc_page_count)
{
WASMMemoryInstance *memory = module->default_memory;
uint8 *new_memory_data, *memory_data = memory->memory_data;
uint32 heap_size = memory->heap_data_end - memory->heap_data;
uint32 total_size_old = memory->memory_data_end - memory_data;
uint32 total_page_count = inc_page_count + memory->cur_page_count;
uint64 total_size = memory->num_bytes_per_page * (uint64)total_page_count;
uint8 *heap_data_old = memory->heap_data;
uint8 *new_memory_data, *memory_data, *heap_data_old;
uint32 heap_size, total_size_old, total_page_count;
uint64 total_size;
if (!memory)
return false;
memory_data = memory->memory_data;
heap_size = memory->heap_data_end - memory->heap_data;
total_size_old = memory->memory_data_end - memory_data;
total_page_count = inc_page_count + memory->cur_page_count;
total_size = memory->num_bytes_per_page * (uint64)total_page_count;
heap_data_old = memory->heap_data;
if (inc_page_count <= 0)
/* No need to enlarge memory */
@ -1911,6 +1964,7 @@ wasm_call_indirect(WASMExecEnv *exec_env,
wasm_interp_call_wasm(module_inst, exec_env, function_inst, argc, argv);
(void)clear_wasi_proc_exit_exception(module_inst);
return !wasm_get_exception(module_inst) ? true : false;
got_exception:
@ -2075,6 +2129,9 @@ wasm_get_module_inst_mem_consumption(const WASMModuleInstance *module_inst,
mem_conspn->memories_size += size;
mem_conspn->app_heap_size += memory->heap_data_end
- memory->heap_data;
/* size of app heap structure */
mem_conspn->memories_size +=
mem_allocator_get_heap_struct_size();
}
mem_conspn->tables_size = sizeof(WASMTableInstance *)