Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions core/iwasm/common/wasm_exec_env.h
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,11 @@ typedef struct WASMCurrentEnvStatus WASMCurrentEnvStatus;
typedef struct WASMJmpBuf {
struct WASMJmpBuf *prev;
korp_jmpbuf jmpbuf;
#if WASM_ENABLE_MULTI_MODULE != 0
/* The owner module instance associated with the current jmpbuf. Used in
* multi-module to propagate the exception */
struct WASMModuleInstanceCommon *module_inst;
#endif
} WASMJmpBuf;
#endif

Expand Down
97 changes: 97 additions & 0 deletions core/iwasm/common/wasm_runtime_common.c
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,7 @@ static korp_mutex loading_module_list_lock;
static bh_list registered_module_list_head;
static bh_list *const registered_module_list = &registered_module_list_head;
static korp_mutex registered_module_list_lock;

static void
wasm_runtime_destroy_registered_module_list(void);
#endif /* WASM_ENABLE_MULTI_MODULE */
Expand Down Expand Up @@ -248,6 +249,15 @@ runtime_signal_handler(void *sig_addr)

if (is_sig_addr_in_guard_pages(sig_addr, module_inst)) {
wasm_set_exception(module_inst, "out of bounds memory access");
#if WASM_ENABLE_MULTI_MODULE != 0
if (jmpbuf_node->module_inst
&& jmpbuf_node->module_inst
!= (WASMModuleInstanceCommon *)module_inst) {
wasm_runtime_propagate_exception_from_import(
(WASMModuleInstanceCommon *)jmpbuf_node->module_inst,
(WASMModuleInstanceCommon *)module_inst);
}
#endif
os_longjmp(jmpbuf_node->jmpbuf, 1);
}
#if WASM_DISABLE_STACK_HW_BOUND_CHECK == 0
Expand Down Expand Up @@ -375,6 +385,15 @@ runtime_exception_handler(EXCEPTION_POINTERS *exce_info)
the wasm func returns, the caller will check whether the
exception is thrown and return to runtime. */
wasm_set_exception(module_inst, "out of bounds memory access");
#if WASM_ENABLE_MULTI_MODULE != 0
if (jmpbuf_node->module_inst
&& jmpbuf_node->module_inst
!= (WASMModuleInstanceCommon *)module_inst) {
wasm_runtime_propagate_exception_from_import(
(WASMModuleInstance *)jmpbuf_node->module_inst,
module_inst);
}
#endif
ret = next_action(module_inst, exce_info);
if (ret == EXCEPTION_CONTINUE_SEARCH
|| ret == EXCEPTION_CONTINUE_EXECUTION)
Expand Down Expand Up @@ -1352,6 +1371,84 @@ wasm_runtime_destroy_loading_module_list()

os_mutex_unlock(&loading_module_list_lock);
}

void
wasm_runtime_propagate_exception_from_import(
WASMModuleInstanceCommon *parent, WASMModuleInstanceCommon *sub_module)
{
static const uint32 exception_prefix_len = sizeof("Exception: ") - 1;
static const char memory_oob_exception[] = "out of bounds memory access";
char exception_buf[EXCEPTION_BUF_LEN] = { 0 };
const char *message = NULL;
bool has_exception = false;

if (!parent || !sub_module)
return;

switch (sub_module->module_type) {
#if WASM_ENABLE_INTERP != 0
case Wasm_Module_Bytecode:
has_exception = wasm_copy_exception(
(WASMModuleInstance *)sub_module, exception_buf);
break;
#endif
#if WASM_ENABLE_AOT != 0
case Wasm_Module_AoT:
has_exception = aot_copy_exception((AOTModuleInstance *)sub_module,
exception_buf);
break;
#endif
default:
return;
}

if (has_exception) {
message = exception_buf;
if (strlen(message) >= exception_prefix_len) {
message += exception_prefix_len;
}
else {
LOG_WARNING("sub-module exception format unexpected: %s", message);
return;
}

if (strcmp(message, memory_oob_exception) != 0) {
LOG_WARNING("skip propagating non-memory-OOB exception: %s",
message);
return;
}

switch (parent->module_type) {
#if WASM_ENABLE_INTERP != 0
case Wasm_Module_Bytecode:
wasm_set_exception((WASMModuleInstance *)parent, message);
break;
#endif
#if WASM_ENABLE_AOT != 0
case Wasm_Module_AoT:
aot_set_exception((AOTModuleInstance *)parent, message);
break;
#endif
default:
break;
}

switch (sub_module->module_type) {
#if WASM_ENABLE_INTERP != 0
case Wasm_Module_Bytecode:
wasm_set_exception((WASMModuleInstance *)sub_module, NULL);
break;
#endif
#if WASM_ENABLE_AOT != 0
case Wasm_Module_AoT:
aot_set_exception((AOTModuleInstance *)sub_module, NULL);
break;
#endif
default:
break;
}
}
}
#endif /* WASM_ENABLE_MULTI_MODULE */

bool
Expand Down
6 changes: 6 additions & 0 deletions core/iwasm/common/wasm_runtime_common.h
Original file line number Diff line number Diff line change
Expand Up @@ -578,6 +578,12 @@ typedef struct WASMRegisteredModule {
uint8 *orig_file_buf;
uint32 orig_file_buf_size;
} WASMRegisteredModule;

/* Propagate callee's memory OOB exception to caller module in hardware memory
* exception handler */
void
wasm_runtime_propagate_exception_from_import(
WASMModuleInstanceCommon *parent, WASMModuleInstanceCommon *sub_module);
#endif

typedef package_type_t PackageType;
Expand Down
4 changes: 4 additions & 0 deletions core/iwasm/interpreter/wasm_runtime.c
Original file line number Diff line number Diff line change
Expand Up @@ -3621,6 +3621,10 @@ call_wasm_with_hw_bound_check(WASMModuleInstance *module_inst,
return;
}

#if WASM_ENABLE_MULTI_MODULE != 0
jmpbuf_node.module_inst = (WASMModuleInstanceCommon *)module_inst;
#endif

wasm_exec_env_push_jmpbuf(exec_env, &jmpbuf_node);

if (os_setjmp(jmpbuf_node.jmpbuf) == 0) {
Expand Down
12 changes: 11 additions & 1 deletion tests/regression/ba-issues/build_wamr.sh
Original file line number Diff line number Diff line change
Expand Up @@ -25,8 +25,15 @@ function build_iwasm() {
cd ${WORK_DIR}/build &&
if [ -d build-iwasm-$2 ]; then rm -rf build-iwasm-$2; else mkdir build-iwasm-$2; fi &&
cd build-iwasm-$2 &&

# default: enable asan, when pass false, disable asan
SANITIZER_FLAG="-DWAMR_BUILD_SANITIZER=asan"
if [ "$3" = "false" ]; then
SANITIZER_FLAG=""
fi

cmake ${WAMR_DIR}/product-mini/platforms/${PLATFORM} $1 \
-DCMAKE_BUILD_TYPE=Debug -DWAMR_BUILD_SANITIZER=asan &&
-DCMAKE_BUILD_TYPE=Debug ${SANITIZER_FLAG} &&
make -j 4
if [ "$?" != 0 ]; then
echo -e "build iwasm failed"
Expand Down Expand Up @@ -60,4 +67,7 @@ build_iwasm "-DWAMR_BUILD_REF_TYPES=1 -DWAMR_BUILD_JIT=1 -DWAMR_BUILD_LIBC_WASI=
# build multi-tier-jit iwasm for testing classic-interp, fast-jit, llvm-jit and multi-tier-jit with libc-wasi disabled
build_iwasm "-DWAMR_BUILD_REF_TYPES=1 -DWAMR_BUILD_FAST_JIT=1 -DWAMR_BUILD_JIT=1 -DWAMR_BUILD_LIBC_WASI=0" "multi-tier-jit-wasi-disabled"

# build default iwasm for testing multi-module
build_iwasm "-DWAMR_BUILD_MULTI_MODULE=1 -DWAMR_BUILD_MULTI_MEMORY=1 -DWAMR_BUILD_AOT=0 -DWAMR_BUILD_FAST_INTERP=0" "multi-memory-multi-module" "false"

# TODO: add more version of iwasm, for example, sgx version
Binary file not shown.
Binary file not shown.
18 changes: 17 additions & 1 deletion tests/regression/ba-issues/running_config.json
Original file line number Diff line number Diff line change
Expand Up @@ -1818,6 +1818,22 @@
"stdout content": "Exception: unsupported opcode",
"description": "classic-interp will exit gracefully when meeting simd opcodes"
}
},
{
"deprecated": false,
"ids": [
4703
],
"runtime": "iwasm-multi-memory-multi-module",
"file": "single_page_memory.wasm",
"mode": "classic-interp",
"options": "--module-path=./issues/issue-4703",
"argument": "",
"expected return": {
"ret code": 1,
"stdout content": "Exception: out of bounds memory access",
"description": "when encounter memory OOB in sub-module when hardware bondary check is enabled, report exception correctly instead of silent exit"
}
}
]
}
}
Loading