Enhance wasm loader and interpreter, enhance code security and update document (#149)

This commit is contained in:
wenyongh
2019-12-13 15:30:30 +08:00
committed by GitHub
parent 1c81ad6da5
commit 631b7a2403
45 changed files with 678 additions and 646 deletions

View File

@ -3,318 +3,13 @@
* SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
*/
#ifndef _GNU_SOURCE
#define _GNU_SOURCE /* for O_DIRECT */
#endif
#include "wasm_native.h"
#include "wasm_runtime.h"
#include "wasm_log.h"
#include "wasm_memory.h"
#include "wasm_platform_log.h"
#include "bh_common.h"
#include <sys/types.h>
#include <unistd.h>
#include <errno.h>
#define validate_app_addr(offset, size) \
wasm_runtime_validate_app_addr(module_inst, offset, size)
#define addr_app_to_native(offset) \
wasm_runtime_addr_app_to_native(module_inst, offset)
#define addr_native_to_app(ptr) \
wasm_runtime_addr_native_to_app(module_inst, ptr)
#define module_malloc(size) \
wasm_runtime_module_malloc(module_inst, size)
#define module_free(offset) \
wasm_runtime_module_free(module_inst, offset)
static int32
__syscall0_wrapper(WASMModuleInstance *module_inst, int32 arg0)
{
switch (arg0) {
case 199: /* getuid */
/* TODO */
default:
bh_printf("##_syscall0 called, syscall id: %d\n", arg0);
}
return 0;
}
static int32
__syscall1_wrapper(WASMModuleInstance *module_inst, int32 arg0, int32 arg1)
{
switch (arg0) {
case 6: /* close */
/* TODO */
default:
bh_printf("##_syscall1 called, syscall id: %d\n", arg0);
}
return 0;
}
static int32
__syscall2_wrapper(WASMModuleInstance *module_inst,
int32 arg0, int32 arg1, int32 arg2)
{
switch (arg0) {
case 183: /* getcwd */
/* TODO */
default:
bh_printf("##_syscall2 called, syscall id: %d\n", arg0);
}
return 0;
}
static int32
__syscall3_wrapper(WASMModuleInstance *module_inst,
int32 arg0, int32 arg1, int32 arg2, int32 arg3)
{
switch (arg0) {
case 146: /* writev */
{
/* Implement syscall 54 and syscall 146 to support printf()
for non SIDE_MODULE=1 mode */
struct iovec_app {
int32 iov_base_offset;
uint32 iov_len;
} *vec;
int32 vec_offset = arg2, str_offset;
uint32 iov_count = (uint32)arg3, i;
int32 count = 0;
char *iov_base, *str;
if (!validate_app_addr(vec_offset, sizeof(struct iovec_app)))
return 0;
vec = (struct iovec_app *)addr_app_to_native(vec_offset);
for (i = 0; i < iov_count; i++, vec++) {
if (vec->iov_len > 0) {
if (!validate_app_addr(vec->iov_base_offset, 1))
return 0;
iov_base = (char*)addr_app_to_native(vec->iov_base_offset);
if (!(str_offset = module_malloc(vec->iov_len + 1)))
return 0;
str = addr_app_to_native(str_offset);
bh_memcpy_s(str, vec->iov_len + 1, iov_base, vec->iov_len);
str[vec->iov_len] = '\0';
count += wasm_printf("%s", str);
module_free(str_offset);
}
}
return count;
}
case 145: /* readv */
case 3: /* read*/
case 5: /* open */
case 221: /* fcntl */
/* TODO */
default:
bh_printf("##_syscall3 called, syscall id: %d\n", arg0);
}
return 0;
}
static int32
__syscall4_wrapper(WASMModuleInstance *module_inst,
int32 arg0, int32 arg1, int32 arg2,
int32 arg3, int32 arg4)
{
bh_printf("##_syscall4 called, syscall id: %d\n", arg0);
return 0;
}
static int32
__syscall5_wrapper(WASMModuleInstance *module_inst,
int32 arg0, int32 arg1, int32 arg2,
int32 arg3, int32 arg4, int32 arg5)
{
switch (arg0) {
case 140: /* llseek */
/* TODO */
default:
bh_printf("##_syscall5 called, args[0]: %d\n", arg0);
}
return 0;
}
#define GET_EMCC_SYSCALL_ARGS() \
int32 *args; \
if (!validate_app_addr(args_off, 1)) \
return 0; \
args = addr_app_to_native(args_off) \
#define EMCC_SYSCALL_WRAPPER0(id) \
static int32 ___syscall##id##_wrapper(WASMModuleInstance *module_inst,\
int32 _id) { \
return __syscall0_wrapper(module_inst, id); \
}
#define EMCC_SYSCALL_WRAPPER1(id) \
static int32 ___syscall##id##_wrapper(WASMModuleInstance *module_inst,\
int32 _id, int32 args_off) { \
GET_EMCC_SYSCALL_ARGS(); \
return __syscall1_wrapper(module_inst, id, args[0]); \
}
#define EMCC_SYSCALL_WRAPPER2(id) \
static int32 ___syscall##id##_wrapper(WASMModuleInstance *module_inst,\
int32 _id, int32 args_off){ \
GET_EMCC_SYSCALL_ARGS(); \
return __syscall2_wrapper(module_inst, id, args[0], args[1]); \
}
#define EMCC_SYSCALL_WRAPPER3(id) \
static int32 ___syscall##id##_wrapper(WASMModuleInstance *module_inst,\
int32 _id, int32 args_off) { \
GET_EMCC_SYSCALL_ARGS(); \
return __syscall3_wrapper(module_inst, id, \
args[0], args[1], args[2]); \
}
#define EMCC_SYSCALL_WRAPPER4(id) \
static int32 ___syscall##id##_wrapper(WASMModuleInstance *module_inst,\
int32 _id, int32 args_off) { \
GET_EMCC_SYSCALL_ARGS(); \
return __syscall4_wrapper(module_inst, id, \
args[0], args[1], args[2], args[3]); \
}
#define EMCC_SYSCALL_WRAPPER5(id) \
static int32 ___syscall##id##_wrapper(WASMModuleInstance *module_inst,\
int32 _id, int32 args_off) { \
GET_EMCC_SYSCALL_ARGS(); \
return __syscall5_wrapper(module_inst, id, \
args[0], args[1], args[2], \
args[3], args[4]); \
}
EMCC_SYSCALL_WRAPPER0(199)
EMCC_SYSCALL_WRAPPER1(6)
EMCC_SYSCALL_WRAPPER2(183)
EMCC_SYSCALL_WRAPPER3(3)
EMCC_SYSCALL_WRAPPER3(5)
EMCC_SYSCALL_WRAPPER3(54)
EMCC_SYSCALL_WRAPPER3(145)
EMCC_SYSCALL_WRAPPER3(146)
EMCC_SYSCALL_WRAPPER3(221)
EMCC_SYSCALL_WRAPPER5(140)
static uint32
getTotalMemory_wrapper(WASMModuleInstance *module_inst)
{
WASMMemoryInstance *memory = module_inst->default_memory;
return NumBytesPerPage * memory->cur_page_count;
}
static int32
enlargeMemory_wrapper(WASMModuleInstance *module_inst)
{
bool ret;
WASMMemoryInstance *memory = module_inst->default_memory;
uint32 DYNAMICTOP_PTR_offset = module_inst->DYNAMICTOP_PTR_offset;
uint32 addr_data_offset = *(uint32*)(memory->global_data + DYNAMICTOP_PTR_offset);
uint32 *DYNAMICTOP_PTR = (uint32*)(memory->memory_data + addr_data_offset);
uint32 memory_size_expected = *DYNAMICTOP_PTR;
uint32 total_page_count = (memory_size_expected + NumBytesPerPage - 1) / NumBytesPerPage;
if (total_page_count < memory->cur_page_count) {
return 1;
}
else {
ret = wasm_runtime_enlarge_memory(module_inst, total_page_count -
memory->cur_page_count);
return ret ? 1 : 0;
}
}
static void
_abort_wrapper(WASMModuleInstance *module_inst, int32 code)
{
char buf[32];
snprintf(buf, sizeof(buf), "env.abort(%i)", code);
wasm_runtime_set_exception(module_inst, buf);
}
static void
abortOnCannotGrowMemory_wrapper(WASMModuleInstance *module_inst)
{
wasm_runtime_set_exception(module_inst, "abort on cannot grow memory");
}
static void
___setErrNo_wrapper(WASMModuleInstance *module_inst, int32 error_no)
{
errno = error_no;
}
/* TODO: add function parameter/result types check */
#define REG_NATIVE_FUNC(module_name, func_name) \
{#module_name, #func_name, func_name##_wrapper}
typedef struct WASMNativeFuncDef {
const char *module_name;
const char *func_name;
void *func_ptr;
} WASMNativeFuncDef;
static WASMNativeFuncDef native_func_defs[] = {
REG_NATIVE_FUNC(env, __syscall0),
REG_NATIVE_FUNC(env, __syscall1),
REG_NATIVE_FUNC(env, __syscall2),
REG_NATIVE_FUNC(env, __syscall3),
REG_NATIVE_FUNC(env, __syscall4),
REG_NATIVE_FUNC(env, __syscall5),
REG_NATIVE_FUNC(env, ___syscall3),
REG_NATIVE_FUNC(env, ___syscall5),
REG_NATIVE_FUNC(env, ___syscall6),
REG_NATIVE_FUNC(env, ___syscall54),
REG_NATIVE_FUNC(env, ___syscall140),
REG_NATIVE_FUNC(env, ___syscall145),
REG_NATIVE_FUNC(env, ___syscall146),
REG_NATIVE_FUNC(env, ___syscall183),
REG_NATIVE_FUNC(env, ___syscall199),
REG_NATIVE_FUNC(env, ___syscall221),
REG_NATIVE_FUNC(env, _abort),
REG_NATIVE_FUNC(env, abortOnCannotGrowMemory),
REG_NATIVE_FUNC(env, enlargeMemory),
REG_NATIVE_FUNC(env, getTotalMemory),
REG_NATIVE_FUNC(env, ___setErrNo),
};
void*
wasm_platform_native_func_lookup(const char *module_name,
const char *func_name)
{
uint32 size = sizeof(native_func_defs) / sizeof(WASMNativeFuncDef);
WASMNativeFuncDef *func_def = native_func_defs;
WASMNativeFuncDef *func_def_end = func_def + size;
if (!module_name || !func_name)
return NULL;
while (func_def < func_def_end) {
if (!strcmp(func_def->module_name, module_name)
&& !strcmp(func_def->func_name, func_name))
return (void*)(uintptr_t)func_def->func_ptr;
func_def++;
}
return NULL;
}