Fix potential pointer overflows (#826)

Fix some potential pointer overflows in aot applying relocations and
several other places.
And add sanitizer compiler flags to wamrc CMakeLists.txt to detect
such issues.
This commit is contained in:
Wenyong Huang 2021-11-15 10:57:37 +08:00 committed by GitHub
parent a1ad950ae1
commit 64be6ec9a7
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
21 changed files with 103 additions and 65 deletions

View File

@ -2038,7 +2038,8 @@ load_relocation_section(const uint8 *buf, const uint8 *buf_end,
for (j = 0; j < relocation_count; j++) {
AOTRelocation relocation = { 0 };
uint32 symbol_index, offset32, addend32;
uint32 symbol_index, offset32;
int32 addend32;
uint16 symbol_name_len;
uint8 *symbol_name;
@ -2050,7 +2051,7 @@ load_relocation_section(const uint8 *buf, const uint8 *buf_end,
read_uint32(buf, buf_end, offset32);
relocation.relocation_offset = (uint64)offset32;
read_uint32(buf, buf_end, addend32);
relocation.relocation_addend = (uint64)addend32;
relocation.relocation_addend = (int64)addend32;
}
read_uint32(buf, buf_end, relocation.relocation_type);
read_uint32(buf, buf_end, symbol_index);

View File

@ -153,7 +153,7 @@ get_current_target(char *target_buf, uint32 target_buf_size);
bool
apply_relocation(AOTModule *module,
uint8 *target_section_addr, uint32 target_section_size,
uint64 reloc_offset, uint64 reloc_addend,
uint64 reloc_offset, int64 reloc_addend,
uint32 reloc_type, void *symbol_addr, int32 symbol_index,
char *error_buf, uint32 error_buf_size);
/* clang-format off */

View File

@ -2087,7 +2087,7 @@ aot_enlarge_memory(AOTModuleInstance *module_inst, uint32 inc_page_count)
}
}
heap_data = heap_data_old + (memory_data - memory_data_old);
heap_data = memory_data + (heap_data_old - memory_data_old);
memory_inst->heap_data.ptr = heap_data;
memory_inst->heap_data_end.ptr = heap_data + heap_size;

View File

@ -64,7 +64,7 @@ typedef struct AOTObjectDataSection {
/* Relocation info */
typedef struct AOTRelocation {
uint64 relocation_offset;
uint64 relocation_addend;
int64 relocation_addend;
uint32 relocation_type;
char *symbol_name;
/* index in the symbol offset field */

View File

@ -138,7 +138,7 @@ check_reloc_offset(uint32 target_section_size, uint64 reloc_offset,
bool
apply_relocation(AOTModule *module, uint8 *target_section_addr,
uint32 target_section_size, uint64 reloc_offset,
uint64 reloc_addend, uint32 reloc_type, void *symbol_addr,
int64 reloc_addend, uint32 reloc_type, void *symbol_addr,
int32 symbol_index, char *error_buf, uint32 error_buf_size)
{
switch (reloc_type) {

View File

@ -164,7 +164,7 @@ middle_endian_convert(uint32 insn)
bool
apply_relocation(AOTModule *module, uint8 *target_section_addr,
uint32 target_section_size, uint64 reloc_offset,
uint64 reloc_addend, uint32 reloc_type, void *symbol_addr,
int64 reloc_addend, uint32 reloc_type, void *symbol_addr,
int32 symbol_index, char *error_buf, uint32 error_buf_size)
{
switch (reloc_type) {
@ -172,7 +172,8 @@ apply_relocation(AOTModule *module, uint8 *target_section_addr,
{
uint32 insn = LOAD_I32(target_section_addr + reloc_offset);
int32 addend, value;
uintptr_t S, A, P;
uintptr_t S, P;
intptr_t A;
CHECK_RELOC_OFFSET(sizeof(void *));
@ -190,7 +191,7 @@ apply_relocation(AOTModule *module, uint8 *target_section_addr,
/* (S + A) - P */
S = (uintptr_t)(uint8 *)symbol_addr;
A = (uintptr_t)reloc_addend;
A = (intptr_t)reloc_addend;
P = (uintptr_t)(target_section_addr + reloc_offset);
P &= (uintptr_t)~3;
value = (int32)(S + A + addend - P);
@ -214,7 +215,7 @@ apply_relocation(AOTModule *module, uint8 *target_section_addr,
CHECK_RELOC_OFFSET(sizeof(void *));
/* (S + A) */
insn = (uint32)(uintptr_t)((uint8 *)symbol_addr + reloc_addend);
insn = (uint32)((uintptr_t)symbol_addr + (intptr_t)reloc_addend);
if (reloc_type == R_ARC_32_ME)
/* Convert to middle endian */

View File

@ -198,7 +198,7 @@ check_reloc_offset(uint32 target_section_size, uint64 reloc_offset,
bool
apply_relocation(AOTModule *module, uint8 *target_section_addr,
uint32 target_section_size, uint64 reloc_offset,
uint64 reloc_addend, uint32 reloc_type, void *symbol_addr,
int64 reloc_addend, uint32 reloc_type, void *symbol_addr,
int32 symbol_index, char *error_buf, uint32 error_buf_size)
{
switch (reloc_type) {
@ -222,8 +222,10 @@ apply_relocation(AOTModule *module, uint8 *target_section_addr,
*/
/* operation: ((S + A) | T) - P where S is symbol address and T
* is 0 */
result = (intptr_t)((uint8 *)symbol_addr + reloc_addend
- (target_section_addr + reloc_offset));
result =
(intptr_t)((uintptr_t)symbol_addr + (intptr_t)reloc_addend
- (uintptr_t)(target_section_addr
+ reloc_offset));
}
else {
if (reloc_addend > 0) {
@ -244,8 +246,9 @@ apply_relocation(AOTModule *module, uint8 *target_section_addr,
uint8 *plt = (uint8 *)module->code + module->code_size
- get_plt_table_size()
+ get_plt_item_size() * symbol_index;
result = (intptr_t)(plt + reloc_addend
- (target_section_addr + reloc_offset));
result = (intptr_t)((uintptr_t)plt + (intptr_t)reloc_addend
- (uintptr_t)(target_section_addr
+ reloc_offset));
}
result += initial_addend;
@ -270,8 +273,9 @@ apply_relocation(AOTModule *module, uint8 *target_section_addr,
CHECK_RELOC_OFFSET(sizeof(void *));
initial_addend =
*(intptr_t *)(target_section_addr + (uint32)reloc_offset);
*(uint8 **)(target_section_addr + reloc_offset) =
(uint8 *)symbol_addr + initial_addend + reloc_addend;
*(uintptr_t *)(target_section_addr + reloc_offset) =
(uintptr_t)symbol_addr + initial_addend
+ (intptr_t)reloc_addend;
break;
}

View File

@ -48,7 +48,7 @@ get_plt_table_size()
bool
apply_relocation(AOTModule *module, uint8 *target_section_addr,
uint32 target_section_size, uint64 reloc_offset,
uint64 reloc_addend, uint32 reloc_type, void *symbol_addr,
int64 reloc_addend, uint32 reloc_type, void *symbol_addr,
int32 symbol_index, char *error_buf, uint32 error_buf_size)
{
switch (reloc_type) {

View File

@ -205,7 +205,7 @@ check_reloc_offset(uint32 target_section_size, uint64 reloc_offset,
bool
apply_relocation(AOTModule *module, uint8 *target_section_addr,
uint32 target_section_size, uint64 reloc_offset,
uint64 reloc_addend, uint32 reloc_type, void *symbol_addr,
int64 reloc_addend, uint32 reloc_type, void *symbol_addr,
int32 symbol_index, char *error_buf, uint32 error_buf_size)
{
int32 val, imm_hi, imm_lo, insn;
@ -216,10 +216,10 @@ apply_relocation(AOTModule *module, uint8 *target_section_addr,
case R_RISCV_32:
{
uint32 val_32 =
(uint32)(uintptr_t)((uint8 *)symbol_addr + reloc_addend);
(uint32)((uintptr_t)symbol_addr + (intptr_t)reloc_addend);
CHECK_RELOC_OFFSET(sizeof(uint32));
if (val_32 != (uintptr_t)((uint8 *)symbol_addr + reloc_addend)) {
if (val_32 != ((uintptr_t)symbol_addr + (intptr_t)reloc_addend)) {
goto fail_addr_out_of_range;
}
@ -229,7 +229,7 @@ apply_relocation(AOTModule *module, uint8 *target_section_addr,
case R_RISCV_64:
{
uint64 val_64 =
(uint64)(uintptr_t)((uint8 *)symbol_addr + reloc_addend);
(uint64)((uintptr_t)symbol_addr + (intptr_t)reloc_addend);
CHECK_RELOC_OFFSET(sizeof(uint64));
bh_memcpy_s(addr, 8, &val_64, 8);
break;
@ -273,10 +273,10 @@ apply_relocation(AOTModule *module, uint8 *target_section_addr,
case R_RISCV_HI20:
{
val = (int32)(intptr_t)((uint8 *)symbol_addr + reloc_addend);
val = (int32)((intptr_t)symbol_addr + (intptr_t)reloc_addend);
CHECK_RELOC_OFFSET(sizeof(uint32));
if (val != (intptr_t)((uint8 *)symbol_addr + reloc_addend)) {
if (val != ((intptr_t)symbol_addr + (intptr_t)reloc_addend)) {
goto fail_addr_out_of_range;
}
@ -290,10 +290,10 @@ apply_relocation(AOTModule *module, uint8 *target_section_addr,
case R_RISCV_LO12_I:
{
val = (int32)(intptr_t)((uint8 *)symbol_addr + reloc_addend);
val = (int32)((intptr_t)symbol_addr + (intptr_t)reloc_addend);
CHECK_RELOC_OFFSET(sizeof(uint32));
if (val != (intptr_t)((uint8 *)symbol_addr + reloc_addend)) {
if (val != (intptr_t)symbol_addr + (intptr_t)reloc_addend) {
goto fail_addr_out_of_range;
}
@ -307,10 +307,10 @@ apply_relocation(AOTModule *module, uint8 *target_section_addr,
case R_RISCV_LO12_S:
{
val = (int32)(intptr_t)((uint8 *)symbol_addr + reloc_addend);
val = (int32)((intptr_t)symbol_addr + (intptr_t)reloc_addend);
CHECK_RELOC_OFFSET(sizeof(uint32));
if (val != (intptr_t)((uint8 *)symbol_addr + reloc_addend)) {
if (val != ((intptr_t)symbol_addr + (intptr_t)reloc_addend)) {
goto fail_addr_out_of_range;
}

View File

@ -238,7 +238,7 @@ check_reloc_offset(uint32 target_section_size, uint64 reloc_offset,
bool
apply_relocation(AOTModule *module, uint8 *target_section_addr,
uint32 target_section_size, uint64 reloc_offset,
uint64 reloc_addend, uint32 reloc_type, void *symbol_addr,
int64 reloc_addend, uint32 reloc_type, void *symbol_addr,
int32 symbol_index, char *error_buf, uint32 error_buf_size)
{
switch (reloc_type) {
@ -269,7 +269,8 @@ apply_relocation(AOTModule *module, uint8 *target_section_addr,
/* operation: ((S + A) | T) - P where S is symbol address
and T is 1 */
result =
(int32)(((intptr_t)((uint8 *)symbol_addr + reloc_addend)
(int32)(((intptr_t)((uintptr_t)symbol_addr
+ (intptr_t)reloc_addend)
| 1)
- (intptr_t)(target_section_addr + reloc_offset));
}

View File

@ -105,7 +105,7 @@ check_reloc_offset(uint32 target_section_size, uint64 reloc_offset,
bool
apply_relocation(AOTModule *module, uint8 *target_section_addr,
uint32 target_section_size, uint64 reloc_offset,
uint64 reloc_addend, uint32 reloc_type, void *symbol_addr,
int64 reloc_addend, uint32 reloc_type, void *symbol_addr,
int32 symbol_index, char *error_buf, uint32 error_buf_size)
{
switch (reloc_type) {
@ -115,8 +115,9 @@ apply_relocation(AOTModule *module, uint8 *target_section_addr,
CHECK_RELOC_OFFSET(sizeof(void *));
value = *(intptr_t *)(target_section_addr + (uint32)reloc_offset);
*(uint8 **)(target_section_addr + reloc_offset) =
(uint8 *)symbol_addr + reloc_addend + value; /* S + A */
*(uintptr_t *)(target_section_addr + reloc_offset) =
(uintptr_t)symbol_addr + (intptr_t)reloc_addend
+ value; /* S + A */
break;
}
@ -132,8 +133,9 @@ apply_relocation(AOTModule *module, uint8 *target_section_addr,
CHECK_RELOC_OFFSET(sizeof(void *));
value = *(int32 *)(target_section_addr + (uint32)reloc_offset);
*(uint32 *)(target_section_addr + (uint32)reloc_offset) =
(uint32)((uint8 *)symbol_addr + (uint32)reloc_addend
- (uint8 *)(target_section_addr + (uint32)reloc_offset)
(uint32)((uintptr_t)symbol_addr + (intptr_t)reloc_addend
- (uintptr_t)(target_section_addr
+ (uint32)reloc_offset)
+ value); /* S + A - P */
break;
}

View File

@ -122,7 +122,7 @@ check_reloc_offset(uint32 target_section_size, uint64 reloc_offset,
bool
apply_relocation(AOTModule *module, uint8 *target_section_addr,
uint32 target_section_size, uint64 reloc_offset,
uint64 reloc_addend, uint32 reloc_type, void *symbol_addr,
int64 reloc_addend, uint32 reloc_type, void *symbol_addr,
int32 symbol_index, char *error_buf, uint32 error_buf_size)
{
switch (reloc_type) {
@ -136,8 +136,8 @@ apply_relocation(AOTModule *module, uint8 *target_section_addr,
CHECK_RELOC_OFFSET(sizeof(void *));
value = *(intptr_t *)(target_section_addr + (uint32)reloc_offset);
*(uint8 **)(target_section_addr + reloc_offset) =
(uint8 *)symbol_addr + reloc_addend + value; /* S + A */
*(uintptr_t *)(target_section_addr + reloc_offset) =
(uintptr_t)symbol_addr + reloc_addend + value; /* S + A */
break;
}
#if defined(BH_PLATFORM_WINDOWS)
@ -166,8 +166,8 @@ apply_relocation(AOTModule *module, uint8 *target_section_addr,
case R_X86_64_PC32:
{
intptr_t target_addr = (intptr_t) /* S + A - P */
((uint8 *)symbol_addr + reloc_addend
- (target_section_addr + reloc_offset));
((uintptr_t)symbol_addr + reloc_addend
- (uintptr_t)(target_section_addr + reloc_offset));
CHECK_RELOC_OFFSET(sizeof(int32));
if ((int32)target_addr != target_addr) {
@ -186,8 +186,8 @@ apply_relocation(AOTModule *module, uint8 *target_section_addr,
case R_X86_64_32S:
{
char buf[128];
uintptr_t target_addr = (uintptr_t) /* S + A */
((uint8 *)symbol_addr + reloc_addend);
uintptr_t target_addr = /* S + A */
(uintptr_t)symbol_addr + reloc_addend;
CHECK_RELOC_OFFSET(sizeof(int32));

View File

@ -145,7 +145,7 @@ typedef union {
bool
apply_relocation(AOTModule *module, uint8 *target_section_addr,
uint32 target_section_size, uint64 reloc_offset,
uint64 reloc_addend, uint32 reloc_type, void *symbol_addr,
int64 reloc_addend, uint32 reloc_type, void *symbol_addr,
int32 symbol_index, char *error_buf, uint32 error_buf_size)
{
switch (reloc_type) {
@ -162,8 +162,8 @@ apply_relocation(AOTModule *module, uint8 *target_section_addr,
}
CHECK_RELOC_OFFSET(4);
initial_addend = *(int32 *)insn_addr;
*(uint8 **)insn_addr =
(uint8 *)symbol_addr + initial_addend + reloc_addend;
*(uintptr_t *)insn_addr = (uintptr_t)symbol_addr + initial_addend
+ (intptr_t)reloc_addend;
break;
}
@ -185,7 +185,8 @@ apply_relocation(AOTModule *module, uint8 *target_section_addr,
initial_addend = (int32)imm16 << 2;
*/
reloc_addr = (uint8 *)symbol_addr + reloc_addend;
reloc_addr =
(uint8 *)((uintptr_t)symbol_addr + (intptr_t)reloc_addend);
if ((intptr_t)reloc_addr & 3) {
set_error_buf(error_buf, error_buf_size,

View File

@ -2947,10 +2947,12 @@ typedef int32 (*Int32FuncPtr)(GenericFunctionPointer f, uint32 *, uint32);
typedef void (*VoidFuncPtr)(GenericFunctionPointer f, uint32 *, uint32);
static Int64FuncPtr invokeNative_Int64 = (Int64FuncPtr)invokeNative;
static Int32FuncPtr invokeNative_Int32 = (Int32FuncPtr)invokeNative;
static Float64FuncPtr invokeNative_Float64 = (Float64FuncPtr)invokeNative;
static Float32FuncPtr invokeNative_Float32 = (Float32FuncPtr)invokeNative;
static VoidFuncPtr invokeNative_Void = (VoidFuncPtr)invokeNative;
static Int32FuncPtr invokeNative_Int32 = (Int32FuncPtr)(uintptr_t)invokeNative;
static Float64FuncPtr invokeNative_Float64 =
(Float64FuncPtr)(uintptr_t)invokeNative;
static Float32FuncPtr invokeNative_Float32 =
(Float32FuncPtr)(uintptr_t)invokeNative;
static VoidFuncPtr invokeNative_Void = (VoidFuncPtr)(uintptr_t)invokeNative;
static inline void
word_copy(uint32 *dest, uint32 *src, unsigned num)

View File

@ -2351,16 +2351,16 @@ aot_resolve_object_relocation_group(AOTObjectData *obj_data,
/* parse relocation addend from reloction content */
if (has_addend) {
if (is_binary_32bit) {
uint32 addend =
(uint32)(((struct elf32_rela *)rela_content)->r_addend);
int32 addend =
(int32)(((struct elf32_rela *)rela_content)->r_addend);
if (is_binary_little_endian != is_little_endian())
exchange_uint32((uint8 *)&addend);
relocation->relocation_addend = (uint64)addend;
relocation->relocation_addend = (int64)addend;
rela_content += sizeof(struct elf32_rela);
}
else {
uint64 addend =
(uint64)(((struct elf64_rela *)rela_content)->r_addend);
int64 addend =
(int64)(((struct elf64_rela *)rela_content)->r_addend);
if (is_binary_little_endian != is_little_endian())
exchange_uint64((uint8 *)&addend);
relocation->relocation_addend = addend;

View File

@ -422,9 +422,14 @@ aot_compile_op_block(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
/* Init aot block data */
block->label_type = label_type;
block->param_count = param_count;
memcpy(block->param_types, param_types, param_count);
if (param_count) {
bh_memcpy_s(block->param_types, param_count, param_types, param_count);
}
block->result_count = result_count;
memcpy(block->result_types, result_types, result_count);
if (result_count) {
bh_memcpy_s(block->result_types, result_count, result_types,
result_count);
}
block->wasm_code_else = else_addr;
block->wasm_code_end = end_addr;
block->block_index = func_ctx->block_stack.block_index[label_type];

View File

@ -162,10 +162,15 @@ aot_create_func_block(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
/* Set block data */
aot_block->label_type = LABEL_TYPE_FUNCTION;
aot_block->param_count = param_count;
memcpy(aot_block->param_types, aot_func_type->types, param_count);
if (param_count) {
bh_memcpy_s(aot_block->param_types, param_count, aot_func_type->types,
param_count);
}
aot_block->result_count = result_count;
memcpy(aot_block->result_types, aot_func_type->types + param_count,
result_count);
if (result_count) {
bh_memcpy_s(aot_block->result_types, result_count,
aot_func_type->types + param_count, result_count);
}
aot_block->wasm_code_end = func->code + func->code_size;
/* Add function entry block */

View File

@ -2124,7 +2124,7 @@ wasm_enlarge_memory(WASMModuleInstance *module, uint32 inc_page_count)
memory->memory_data = new_memory_data;
memory->cur_page_count = total_page_count;
memory->heap_data = heap_data_old + (new_memory_data - memory_data);
memory->heap_data = new_memory_data + (heap_data_old - memory_data);
memory->heap_data_end = memory->heap_data + heap_size;
memory->memory_data_end =
memory->memory_data + memory->num_bytes_per_page * total_page_count;

View File

@ -759,7 +759,7 @@ gci_dump(gc_heap_t *heap)
else if (ut == HMU_FC)
inuse = 'F';
if (size == 0 || size > (uint8 *)end - (uint8 *)cur) {
if (size == 0 || size > (uint32)((uint8 *)end - (uint8 *)cur)) {
os_printf("[GC_ERROR]Heap is corrupted, heap dump failed.\n");
heap->is_heap_corrupted = true;
return;

View File

@ -199,7 +199,7 @@ gc_migrate(gc_handle_t handle, char *pool_buf_new, gc_size_t pool_buf_size)
while (cur < end) {
size = hmu_get_size(cur);
if (size <= 0 || size > (uint8 *)end - (uint8 *)cur) {
if (size <= 0 || size > (uint32)((uint8 *)end - (uint8 *)cur)) {
os_printf("[GC_ERROR]Heap is corrupted, heap migrate failed.\n");
heap->is_heap_corrupted = true;
return GC_ERROR;

View File

@ -186,6 +186,21 @@ include (${IWASM_DIR}/compilation/iwasm_compl.cmake)
if (WAMR_BUILD_TARGET MATCHES "X86_.*" OR WAMR_BUILD_TARGET STREQUAL "AMD_64")
if (NOT (CMAKE_C_COMPILER MATCHES ".*clang.*" OR CMAKE_C_COMPILER_ID MATCHES ".*Clang" OR MSVC))
set (CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -mindirect-branch-register")
# UNDEFINED BEHAVIOR, refer to https://en.cppreference.com/w/cpp/language/ub
if(CMAKE_BUILD_TYPE STREQUAL "Debug" AND NOT WAMR_BUILD_JIT EQUAL 1)
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fsanitize=undefined \
-fno-sanitize=bounds,bounds-strict,alignment \
-fno-sanitize-recover")
set(lib_ubsan ubsan)
endif()
else ()
# UNDEFINED BEHAVIOR, refer to https://en.cppreference.com/w/cpp/language/ub
if(CMAKE_BUILD_TYPE STREQUAL "Debug" AND NOT WAMR_BUILD_JIT EQUAL 1)
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fsanitize=undefined \
-fno-sanitize=bounds,alignment \
-fno-sanitize-recover")
set(lib_ubsan ubsan)
endif()
endif()
endif ()
@ -225,7 +240,8 @@ add_library (aotclib ${IWASM_COMPL_SOURCE})
add_executable (wamrc main.c)
if (NOT MSVC)
target_link_libraries (wamrc aotclib vmlib LLVMDemangle ${LLVM_AVAILABLE_LIBS} -lm -ldl -lpthread ${lib_lldb})
target_link_libraries (wamrc aotclib vmlib LLVMDemangle ${LLVM_AVAILABLE_LIBS} ${lib_ubsan}
-lm -ldl -lpthread ${lib_lldb})
else()
target_link_libraries (wamrc aotclib vmlib ${lib_lldb} ${LLVM_AVAILABLE_LIBS})
target_link_libraries (wamrc aotclib vmlib ${lib_lldb} ${LLVM_AVAILABLE_LIBS} ${lib_ubsan})
endif()