Skip to content

Commit

Permalink
Make boundary check behavior configurable
Browse files Browse the repository at this point in the history
Change-Id: Id06b5f9f8b9ef4e29ed0bf70d9b48c5a70ea2853
  • Loading branch information
no1wudi committed Jun 27, 2023
1 parent ab96e01 commit 9d155fa
Show file tree
Hide file tree
Showing 15 changed files with 294 additions and 28 deletions.
4 changes: 4 additions & 0 deletions build-scripts/config_common.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -396,3 +396,7 @@ if (WAMR_DISABLE_WRITE_GS_BASE EQUAL 1)
add_definitions (-DWASM_DISABLE_WRITE_GS_BASE=1)
message (" Write linear memory base addr to x86 GS register disabled")
endif ()
if (WAMR_CONFIGUABLE_BOUNDS_CHECKS EQUAL 1)
add_definitions (-DWASM_CONFIGURABLE_BOUNDS_CHECKS=1)
message (" Configurable bounds checks enabled")
endif ()
6 changes: 6 additions & 0 deletions core/config.h
Original file line number Diff line number Diff line change
Expand Up @@ -456,4 +456,10 @@
#define WASM_DISABLE_WRITE_GS_BASE 0
#endif

/* Configurable bounds check */

#ifndef WASM_CONFIGURABLE_BOUNDS_CHECK
#define WASM_CONFIGURABLE_BOUNDS_CHECK 0
#endif

#endif /* end of _CONFIG_H_ */
4 changes: 4 additions & 0 deletions core/iwasm/aot/aot_runtime.c
Original file line number Diff line number Diff line change
Expand Up @@ -1201,6 +1201,10 @@ aot_instantiate(AOTModule *module, bool is_sub_inst, WASMExecEnv *exec_env_main,
}
#endif

#if WASM_CONFIGUABLE_BOUNDS_CHECKS != 0
((AOTModuleInstanceExtra *)module_inst->e)->disable_bounds_checks = false;
#endif

/* Initialize the thread related data */
if (stack_size == 0)
stack_size = DEFAULT_WASM_STACK_SIZE;
Expand Down
4 changes: 4 additions & 0 deletions core/iwasm/aot/aot_runtime.h
Original file line number Diff line number Diff line change
Expand Up @@ -89,6 +89,10 @@ typedef struct AOTFunctionInstance {

typedef struct AOTModuleInstanceExtra {
CApiFuncImport *c_api_func_imports;
#if WASM_CONFIGUABLE_BOUNDS_CHECKS != 0
/* Disable bounds check or not */
bool disable_bounds_checks;
#endif
} AOTModuleInstanceExtra;

#if defined(OS_ENABLE_HW_BOUND_CHECK) && defined(BH_PLATFORM_WINDOWS)
Expand Down
167 changes: 167 additions & 0 deletions core/iwasm/common/wasm_memory.c
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@

#include "wasm_runtime_common.h"
#include "../interpreter/wasm_runtime.h"
#include "../aot/aot_runtime.h"
#include "bh_platform.h"
#include "mem_alloc.h"

Expand Down Expand Up @@ -274,6 +275,28 @@ wasm_runtime_validate_app_addr(WASMModuleInstanceCommon *module_inst_comm,
goto fail;
}

#if WASM_CONFIGUABLE_BOUNDS_CHECKS != 0
#if WASM_ENABLE_AOT != 0
AOTModuleInstanceExtra *ae =
(AOTModuleInstanceExtra *)((AOTModuleInstance *)module_inst_comm)->e;
if (module_inst_comm->module_type == Wasm_Module_AoT) {
if (ae->disable_bounds_checks) {
return true;
}
}
#endif

#if WASM_ENABLE_INTERP != 0
WASMModuleInstanceExtra *ie =
(WASMModuleInstanceExtra *)((WASMModuleInstance *)module_inst_comm)->e;
if (module_inst_comm->module_type == Wasm_Module_Bytecode) {
if (ie->disable_bounds_checks) {
return true;
}
}
#endif
#endif

/* integer overflow check */
if (app_offset > UINT32_MAX - size) {
goto fail;
Expand All @@ -299,6 +322,28 @@ wasm_runtime_validate_app_str_addr(WASMModuleInstanceCommon *module_inst_comm,
bh_assert(module_inst_comm->module_type == Wasm_Module_Bytecode
|| module_inst_comm->module_type == Wasm_Module_AoT);

#if WASM_CONFIGUABLE_BOUNDS_CHECKS != 0
#if WASM_ENABLE_AOT != 0
AOTModuleInstanceExtra *ae =
(AOTModuleInstanceExtra *)((AOTModuleInstance *)module_inst_comm)->e;
if (module_inst_comm->module_type == Wasm_Module_AoT) {
if (ae->disable_bounds_checks) {
return true;
}
}
#endif

#if WASM_ENABLE_INTERP != 0
WASMModuleInstanceExtra *ie =
(WASMModuleInstanceExtra *)((WASMModuleInstance *)module_inst_comm)->e;
if (module_inst_comm->module_type == Wasm_Module_Bytecode) {
if (ie->disable_bounds_checks) {
return true;
}
}
#endif
#endif

if (!wasm_runtime_get_app_addr_range(module_inst_comm, app_str_offset, NULL,
&app_end_offset))
goto fail;
Expand Down Expand Up @@ -327,6 +372,28 @@ wasm_runtime_validate_native_addr(WASMModuleInstanceCommon *module_inst_comm,
bh_assert(module_inst_comm->module_type == Wasm_Module_Bytecode
|| module_inst_comm->module_type == Wasm_Module_AoT);

#if WASM_CONFIGUABLE_BOUNDS_CHECKS != 0
#if WASM_ENABLE_AOT != 0
AOTModuleInstanceExtra *ae =
(AOTModuleInstanceExtra *)((AOTModuleInstance *)module_inst_comm)->e;
if (module_inst_comm->module_type == Wasm_Module_AoT) {
if (ae->disable_bounds_checks) {
return true;
}
}
#endif

#if WASM_ENABLE_INTERP != 0
WASMModuleInstanceExtra *ie =
(WASMModuleInstanceExtra *)((WASMModuleInstance *)module_inst_comm)->e;
if (module_inst_comm->module_type == Wasm_Module_Bytecode) {
if (ie->disable_bounds_checks) {
return true;
}
}
#endif
#endif

memory_inst = wasm_get_default_memory(module_inst);
if (!memory_inst) {
goto fail;
Expand Down Expand Up @@ -358,13 +425,46 @@ wasm_runtime_addr_app_to_native(WASMModuleInstanceCommon *module_inst_comm,
bh_assert(module_inst_comm->module_type == Wasm_Module_Bytecode
|| module_inst_comm->module_type == Wasm_Module_AoT);

#if WASM_CONFIGUABLE_BOUNDS_CHECKS != 0
#if WASM_ENABLE_AOT != 0
AOTModuleInstanceExtra *ae =
(AOTModuleInstanceExtra *)((AOTModuleInstance *)module_inst_comm)->e;
#endif

#if WASM_ENABLE_INTERP != 0
WASMModuleInstanceExtra *ie =
(WASMModuleInstanceExtra *)((WASMModuleInstance *)module_inst_comm)->e;
#endif
#endif

memory_inst = wasm_get_default_memory(module_inst);
if (!memory_inst) {
return NULL;
}

addr = memory_inst->memory_data + app_offset;

#if WASM_CONFIGUABLE_BOUNDS_CHECKS != 0
if (app_offset == 0) {
return NULL;
}
#if WASM_ENABLE_INTERP != 0
if (module_inst_comm->module_type == Wasm_Module_Bytecode) {
if (ie->disable_bounds_checks) {
return addr;
}
}
#endif

#if WASM_ENABLE_AOT != 0
if (module_inst_comm->module_type == Wasm_Module_AoT) {
if (ae->disable_bounds_checks) {
return addr;
}
}
#endif
#endif

if (memory_inst->memory_data <= addr && addr < memory_inst->memory_data_end)
return addr;

Expand All @@ -382,11 +482,44 @@ wasm_runtime_addr_native_to_app(WASMModuleInstanceCommon *module_inst_comm,
bh_assert(module_inst_comm->module_type == Wasm_Module_Bytecode
|| module_inst_comm->module_type == Wasm_Module_AoT);

#if WASM_CONFIGUABLE_BOUNDS_CHECKS != 0
#if WASM_ENABLE_AOT != 0
AOTModuleInstanceExtra *ae =
(AOTModuleInstanceExtra *)((AOTModuleInstance *)module_inst_comm)->e;
#endif

#if WASM_ENABLE_INTERP != 0
WASMModuleInstanceExtra *ie =
(WASMModuleInstanceExtra *)((WASMModuleInstance *)module_inst_comm)->e;
#endif
#endif

memory_inst = wasm_get_default_memory(module_inst);
if (!memory_inst) {
return 0;
}

#if WASM_CONFIGUABLE_BOUNDS_CHECKS != 0
if (addr == NULL) {
return 0;
}
#if WASM_ENABLE_INTERP != 0
if (module_inst_comm->module_type == Wasm_Module_Bytecode) {
if (ie->disable_bounds_checks) {
return (uint32)(addr - memory_inst->memory_data);
}
}
#endif

#if WASM_ENABLE_AOT != 0
if (module_inst_comm->module_type == Wasm_Module_AoT) {
if (ae->disable_bounds_checks) {
return (uint32)(addr - memory_inst->memory_data);
}
}
#endif
#endif

if (memory_inst->memory_data <= addr && addr < memory_inst->memory_data_end)
return (uint32)(addr - memory_inst->memory_data);

Expand Down Expand Up @@ -461,12 +594,46 @@ wasm_check_app_addr_and_convert(WASMModuleInstance *module_inst, bool is_str,
WASMMemoryInstance *memory_inst = wasm_get_default_memory(module_inst);
uint8 *native_addr;

#if WASM_CONFIGUABLE_BOUNDS_CHECKS != 0
#if WASM_ENABLE_INTERP != 0
WASMModuleInstanceExtra *ie = (WASMModuleInstanceExtra *)module_inst->e;
#endif

#if WASM_ENABLE_AOT != 0
AOTModuleInstanceExtra *ae = (AOTModuleInstanceExtra *)module_inst->e;
#endif
#endif

if (!memory_inst) {
goto fail;
}

native_addr = memory_inst->memory_data + app_buf_addr;

#if WASM_CONFIGUABLE_BOUNDS_CHECKS != 0
if (app_buf_addr == 0) {
*p_native_addr = NULL;
return true;
}
#if WASM_ENABLE_INTERP != 0
if (module_inst->module_type == Wasm_Module_Bytecode) {
if (ie->disable_bounds_checks) {
*p_native_addr = native_addr;
return true;
}
}
#endif

#if WASM_ENABLE_AOT != 0
if (module_inst->module_type == Wasm_Module_AoT) {
if (ae->disable_bounds_checks) {
*p_native_addr = native_addr;
return true;
}
}
#endif
#endif

/* No need to check the app_offset and buf_size if memory access
boundary check with hardware trap is enabled */
#ifndef OS_ENABLE_HW_BOUND_CHECK
Expand Down
20 changes: 20 additions & 0 deletions core/iwasm/common/wasm_runtime_common.c
Original file line number Diff line number Diff line change
Expand Up @@ -2482,6 +2482,26 @@ wasm_runtime_get_custom_data(WASMModuleInstanceCommon *module_inst_comm)
return module_inst->custom_data;
}

#if WASM_CONFIGUABLE_BOUNDS_CHECKS != 0
void
wasm_runtime_set_bounds_checks(wasm_module_inst_t module_inst, bool enable)
{
#if WASM_ENABLE_INTERP != 0
if (module_inst->module_type == Wasm_Module_Bytecode) {
((WASMModuleInstanceExtra *)((WASMModuleInstance *)module_inst)->e)
->disable_bounds_checks = enable ? false : true;
}
#endif

#if WASM_ENABLE_AOT != 0
if (module_inst->module_type == Wasm_Module_AoT) {
((AOTModuleInstanceExtra *)((AOTModuleInstance *)module_inst)->e)
->disable_bounds_checks = enable ? false : true;
}
}
#endif
#endif

uint32
wasm_runtime_module_malloc_internal(WASMModuleInstanceCommon *module_inst,
WASMExecEnv *exec_env, uint32 size,
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 @@ -593,6 +593,12 @@ wasm_runtime_set_user_data(WASMExecEnv *exec_env, void *user_data);
WASM_RUNTIME_API_EXTERN void *
wasm_runtime_get_user_data(WASMExecEnv *exec_env);

#if WASM_CONFIGUABLE_BOUNDS_CHECKS != 0
/* See wasm_export.h for description */
WASM_RUNTIME_API_EXTERN void
wasm_runtime_set_bounds_checks(wasm_module_inst_t module_inst, bool enable);
#endif

#ifdef OS_ENABLE_HW_BOUND_CHECK
/* Access exception check guard page to trigger the signal handler */
void
Expand Down
10 changes: 10 additions & 0 deletions core/iwasm/include/wasm_export.h
Original file line number Diff line number Diff line change
Expand Up @@ -914,6 +914,16 @@ wasm_runtime_set_custom_data(wasm_module_inst_t module_inst,
WASM_RUNTIME_API_EXTERN void *
wasm_runtime_get_custom_data(wasm_module_inst_t module_inst);

/**
* Set the memory bounds check flag of a WASM module instance.
*
* @param module_inst the WASM module instance
* @param enable the flag to enable/disable the memory bounds check
*/
WASM_RUNTIME_API_EXTERN void
wasm_runtime_set_bounds_checks(wasm_module_inst_t module_inst,
bool enable);

/**
* Allocate memory from the heap of WASM module instance
*
Expand Down
43 changes: 25 additions & 18 deletions core/iwasm/interpreter/wasm_interp_classic.c
Original file line number Diff line number Diff line change
Expand Up @@ -41,26 +41,28 @@ typedef float64 CellType_F64;

#if !defined(OS_ENABLE_HW_BOUND_CHECK) \
|| WASM_CPU_SUPPORTS_UNALIGNED_ADDR_ACCESS == 0
#define CHECK_MEMORY_OVERFLOW(bytes) \
do { \
uint64 offset1 = (uint64)offset + (uint64)addr; \
if (offset1 + bytes <= (uint64)get_linear_mem_size()) \
/* If offset1 is in valid range, maddr must also \
be in valid range, no need to check it again. */ \
maddr = memory->memory_data + offset1; \
else \
goto out_of_bounds; \
#define CHECK_MEMORY_OVERFLOW(bytes) \
do { \
uint64 offset1 = (uint64)offset + (uint64)addr; \
if (disable_bounds_checks \
|| offset1 + bytes <= (uint64)get_linear_mem_size()) \
/* If offset1 is in valid range, maddr must also \
be in valid range, no need to check it again. */ \
maddr = memory->memory_data + offset1; \
else \
goto out_of_bounds; \
} while (0)

#define CHECK_BULK_MEMORY_OVERFLOW(start, bytes, maddr) \
do { \
uint64 offset1 = (uint32)(start); \
if (offset1 + bytes <= (uint64)get_linear_mem_size()) \
/* App heap space is not valid space for \
bulk memory operation */ \
maddr = memory->memory_data + offset1; \
else \
goto out_of_bounds; \
#define CHECK_BULK_MEMORY_OVERFLOW(start, bytes, maddr) \
do { \
uint64 offset1 = (uint32)(start); \
if (disable_bounds_checks \
|| offset1 + bytes <= (uint64)get_linear_mem_size()) \
/* App heap space is not valid space for \
bulk memory operation */ \
maddr = memory->memory_data + offset1; \
else \
goto out_of_bounds; \
} while (0)
#else
#define CHECK_MEMORY_OVERFLOW(bytes) \
Expand Down Expand Up @@ -1174,6 +1176,11 @@ wasm_interp_call_func_bytecode(WASMModuleInstance *module,
uint8 local_type, *global_addr;
uint32 cache_index, type_index, param_cell_num, cell_num;
uint8 value_type;
#if WASM_CONFIGUABLE_BOUNDS_CHECKS != 0
bool disable_bounds_checks = module->e->disable_bounds_checks;
#else
bool disable_bounds_checks = false;
#endif

#if WASM_ENABLE_DEBUG_INTERP != 0
uint8 *frame_ip_orig = NULL;
Expand Down
Loading

0 comments on commit 9d155fa

Please sign in to comment.