Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Make boundary check behavior configurable #2289

Merged
merged 1 commit into from
Jul 4, 2023
Merged
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
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 ()
5 changes: 5 additions & 0 deletions core/config.h
Original file line number Diff line number Diff line change
Expand Up @@ -456,4 +456,9 @@
#define WASM_DISABLE_WRITE_GS_BASE 0
#endif

/* Configurable bounds checks */
#ifndef WASM_CONFIGURABLE_BOUNDS_CHECKS
#define WASM_CONFIGURABLE_BOUNDS_CHECKS 0
#endif

#endif /* end of _CONFIG_H_ */
4 changes: 4 additions & 0 deletions core/iwasm/aot/aot_runtime.h
Original file line number Diff line number Diff line change
Expand Up @@ -90,6 +90,10 @@ typedef struct AOTFunctionInstance {
typedef struct AOTModuleInstanceExtra {
DefPointer(const uint32 *, stack_sizes);
CApiFuncImport *c_api_func_imports;
#if WASM_CONFIGUABLE_BOUNDS_CHECKS != 0
/* Disable bounds checks or not */
bool disable_bounds_checks;
#endif
} AOTModuleInstanceExtra;

#if defined(OS_ENABLE_HW_BOUND_CHECK) && defined(BH_PLATFORM_WINDOWS)
Expand Down
60 changes: 58 additions & 2 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 @@ -87,6 +88,16 @@ wasm_memory_init_with_allocator(void *_malloc_func, void *_realloc_func,
}
#endif

static inline bool
is_bounds_checks_enabled(WASMModuleInstanceCommon *module_inst)
{
#if WASM_CONFIGUABLE_BOUNDS_CHECKS != 0
return wasm_runtime_is_bounds_checks_enabled(module_inst);
#else
return true;
#endif
}

bool
wasm_runtime_memory_init(mem_alloc_type_t mem_alloc_type,
const MemAllocOption *alloc_option)
Expand Down Expand Up @@ -269,6 +280,10 @@ wasm_runtime_validate_app_addr(WASMModuleInstanceCommon *module_inst_comm,
bh_assert(module_inst_comm->module_type == Wasm_Module_Bytecode
|| module_inst_comm->module_type == Wasm_Module_AoT);

if (!is_bounds_checks_enabled(module_inst_comm)) {
return true;
}

memory_inst = wasm_get_default_memory(module_inst);
if (!memory_inst) {
goto fail;
Expand Down Expand Up @@ -299,6 +314,10 @@ 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 (!is_bounds_checks_enabled(module_inst_comm)) {
return true;
}

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 +346,10 @@ 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 (!is_bounds_checks_enabled(module_inst_comm)) {
return true;
}

memory_inst = wasm_get_default_memory(module_inst);
if (!memory_inst) {
goto fail;
Expand Down Expand Up @@ -354,19 +377,31 @@ wasm_runtime_addr_app_to_native(WASMModuleInstanceCommon *module_inst_comm,
WASMModuleInstance *module_inst = (WASMModuleInstance *)module_inst_comm;
WASMMemoryInstance *memory_inst;
uint8 *addr;
bool bounds_checks;

bh_assert(module_inst_comm->module_type == Wasm_Module_Bytecode
|| module_inst_comm->module_type == Wasm_Module_AoT);

bounds_checks = is_bounds_checks_enabled(module_inst_comm);

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

addr = memory_inst->memory_data + app_offset;

if (memory_inst->memory_data <= addr && addr < memory_inst->memory_data_end)
if (bounds_checks) {
if (memory_inst->memory_data <= addr
&& addr < memory_inst->memory_data_end) {

return addr;
}
}
/* If bounds checks is disabled, return the address directly */
else if (app_offset != 0) {
return addr;
}

return NULL;
}
Expand All @@ -378,17 +413,27 @@ wasm_runtime_addr_native_to_app(WASMModuleInstanceCommon *module_inst_comm,
WASMModuleInstance *module_inst = (WASMModuleInstance *)module_inst_comm;
WASMMemoryInstance *memory_inst;
uint8 *addr = (uint8 *)native_ptr;
bool bounds_checks;

bh_assert(module_inst_comm->module_type == Wasm_Module_Bytecode
|| module_inst_comm->module_type == Wasm_Module_AoT);

bounds_checks = is_bounds_checks_enabled(module_inst_comm);

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

if (memory_inst->memory_data <= addr && addr < memory_inst->memory_data_end)
if (bounds_checks) {
if (memory_inst->memory_data <= addr
&& addr < memory_inst->memory_data_end)
return (uint32)(addr - memory_inst->memory_data);
}
/* If bounds checks is disabled, return the offset directly */
else if (addr != NULL) {
return (uint32)(addr - memory_inst->memory_data);
}

return 0;
}
Expand Down Expand Up @@ -460,13 +505,23 @@ wasm_check_app_addr_and_convert(WASMModuleInstance *module_inst, bool is_str,
{
WASMMemoryInstance *memory_inst = wasm_get_default_memory(module_inst);
uint8 *native_addr;
bool bounds_checks;

if (!memory_inst) {
goto fail;
}

native_addr = memory_inst->memory_data + app_buf_addr;

bounds_checks = is_bounds_checks_enabled((wasm_module_inst_t)module_inst);

if (!bounds_checks) {
if (app_buf_addr == 0) {
native_addr = NULL;
}
goto success;
}

/* 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 All @@ -492,6 +547,7 @@ wasm_check_app_addr_and_convert(WASMModuleInstance *module_inst, bool is_str,
}
#endif

success:
*p_native_addr = (void *)native_addr;
return true;
fail:
Expand Down
48 changes: 48 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,54 @@ 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(WASMModuleInstanceCommon *module_inst,
bool enable)
{
/* Alwary disable bounds checks if hw bounds checks enabled */
#ifdef OS_ENABLE_HW_BOUND_CHECK
enable = false;
#endif
#if WASM_ENABLE_INTERP != 0
if (module_inst->module_type == Wasm_Module_Bytecode) {
((WASMModuleInstanceExtra *)((WASMModuleInstance *)module_inst)->e)
->disable_bounds_checks = enable ? false : true;
wenyongh marked this conversation as resolved.
Show resolved Hide resolved
}
#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
}

bool
wasm_runtime_is_bounds_checks_enabled(WASMModuleInstanceCommon *module_inst)
{

#if WASM_ENABLE_INTERP != 0
if (module_inst->module_type == Wasm_Module_Bytecode) {
return !((WASMModuleInstanceExtra *)((WASMModuleInstance *)module_inst)
->e)
->disable_bounds_checks;
wenyongh marked this conversation as resolved.
Show resolved Hide resolved
}
#endif

#if WASM_ENABLE_AOT != 0
if (module_inst->module_type == Wasm_Module_AoT) {
return !((AOTModuleInstanceExtra *)((WASMModuleInstance *)module_inst)
->e)
->disable_bounds_checks;
}
#endif

return true;
no1wudi marked this conversation as resolved.
Show resolved Hide resolved
}
#endif

uint32
wasm_runtime_module_malloc_internal(WASMModuleInstanceCommon *module_inst,
WASMExecEnv *exec_env, uint32 size,
Expand Down
11 changes: 11 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,17 @@ 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(WASMModuleInstanceCommon *module_inst,
bool enable);

/* See wasm_export.h for description */
WASM_RUNTIME_API_EXTERN bool
wasm_runtime_is_bounds_checks_enabled(WASMModuleInstanceCommon *module_inst);
#endif

#ifdef OS_ENABLE_HW_BOUND_CHECK
/* Access exception check guard page to trigger the signal handler */
void
Expand Down
19 changes: 19 additions & 0 deletions core/iwasm/include/wasm_export.h
Original file line number Diff line number Diff line change
Expand Up @@ -914,6 +914,25 @@ 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 checks flag of a WASM module instance.
*
* @param module_inst the WASM module instance
* @param enable the flag to enable/disable the memory bounds checks
*/
WASM_RUNTIME_API_EXTERN void
wasm_runtime_set_bounds_checks(wasm_module_inst_t module_inst,
bool enable);
/**
* Check if the memory bounds checks flag is enabled for a WASM module instance.
*
* @param module_inst the WASM module instance
*
* @return true if the memory bounds checks flag is enabled, false otherwise
*/
WASM_RUNTIME_API_EXTERN bool
wasm_runtime_is_bounds_checks_enabled(
wasm_module_inst_t module_inst);
/**
* Allocate memory from the heap of WASM module instance
*
Expand Down
44 changes: 26 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,12 @@ 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 = !wasm_runtime_is_bounds_checks_enabled(
(WASMModuleInstanceCommon *)module);
wenyongh marked this conversation as resolved.
Show resolved Hide resolved
#else
bool disable_bounds_checks = false;
#endif

#if WASM_ENABLE_DEBUG_INTERP != 0
uint8 *frame_ip_orig = NULL;
Expand Down
27 changes: 17 additions & 10 deletions core/iwasm/interpreter/wasm_interp_fast.c
Original file line number Diff line number Diff line change
Expand Up @@ -35,23 +35,24 @@ typedef float64 CellType_F64;
#define CHECK_MEMORY_OVERFLOW(bytes) \
do { \
uint64 offset1 = (uint64)offset + (uint64)addr; \
if (offset1 + bytes <= (uint64)get_linear_mem_size()) \
if (disable_bounds_checks \
wenyongh marked this conversation as resolved.
Show resolved Hide resolved
|| 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 <= 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 <= 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 @@ -1199,6 +1200,12 @@ wasm_interp_call_func_bytecode(WASMModuleInstance *module,
uint8 *maddr = NULL;
uint32 local_idx, local_offset, global_idx;
uint8 opcode, local_type, *global_addr;
#if WASM_CONFIGUABLE_BOUNDS_CHECKS != 0
bool disable_bounds_checks = !wasm_runtime_is_bounds_checks_enabled(
(WASMModuleInstanceCommon *)module);
#else
bool disable_bounds_checks = false;
#endif

#if WASM_ENABLE_LABELS_AS_VALUES != 0
#define HANDLE_OPCODE(op) &&HANDLE_##op
Expand Down
4 changes: 4 additions & 0 deletions core/iwasm/interpreter/wasm_runtime.h
Original file line number Diff line number Diff line change
Expand Up @@ -241,6 +241,10 @@ typedef struct WASMModuleInstanceExtra {
&& WASM_ENABLE_LAZY_JIT != 0)
WASMModuleInstance *next;
#endif
#if WASM_CONFIGUABLE_BOUNDS_CHECKS != 0
/* Disable bounds checks or not */
bool disable_bounds_checks;
#endif
} WASMModuleInstanceExtra;

struct AOTFuncPerfProfInfo;
Expand Down
Loading