Prechádzať zdrojové kódy

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.
Wenyong Huang 4 rokov pred
rodič
commit
64be6ec9a7

+ 3 - 2
core/iwasm/aot/aot_loader.c

@@ -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);

+ 1 - 1
core/iwasm/aot/aot_reloc.h

@@ -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 */

+ 1 - 1
core/iwasm/aot/aot_runtime.c

@@ -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;
 

+ 1 - 1
core/iwasm/aot/aot_runtime.h

@@ -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 */

+ 1 - 1
core/iwasm/aot/arch/aot_reloc_aarch64.c

@@ -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) {

+ 5 - 4
core/iwasm/aot/arch/aot_reloc_arc.c

@@ -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 */

+ 11 - 7
core/iwasm/aot/arch/aot_reloc_arm.c

@@ -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;
         }
 

+ 1 - 1
core/iwasm/aot/arch/aot_reloc_mips.c

@@ -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) {

+ 10 - 10
core/iwasm/aot/arch/aot_reloc_riscv.c

@@ -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;
             }
 

+ 3 - 2
core/iwasm/aot/arch/aot_reloc_thumb.c

@@ -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));
             }

+ 7 - 5
core/iwasm/aot/arch/aot_reloc_x86_32.c

@@ -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;
         }

+ 7 - 7
core/iwasm/aot/arch/aot_reloc_x86_64.c

@@ -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));
 

+ 5 - 4
core/iwasm/aot/arch/aot_reloc_xtensa.c

@@ -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,

+ 6 - 4
core/iwasm/common/wasm_runtime_common.c

@@ -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)

+ 5 - 5
core/iwasm/compilation/aot_emit_aot_file.c

@@ -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;

+ 7 - 2
core/iwasm/compilation/aot_emit_control.c

@@ -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];

+ 8 - 3
core/iwasm/compilation/aot_llvm.c

@@ -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 */

+ 1 - 1
core/iwasm/interpreter/wasm_runtime.c

@@ -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;

+ 1 - 1
core/shared/mem-alloc/ems/ems_alloc.c

@@ -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;

+ 1 - 1
core/shared/mem-alloc/ems/ems_kfc.c

@@ -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;

+ 18 - 2
wamr-compiler/CMakeLists.txt

@@ -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()