Fixing UB santizer, LITBASE and assert errors. (#2499)
Some checks failed
Run Test / ${{ matrix.config.name }} (map[arch:x64 build-system:cmake diet-build:OFF enable-asan:OFF name:ubuntu-22.04 x64 cmake os:ubuntu-22.04]) (push) Has been cancelled
Run Test / ${{ matrix.config.name }} (map[arch:x64 build-system:cmake diet-build:OFF enable-asan:ON name:ubuntu-24.04 x64 ASAN os:ubuntu-24.04]) (push) Has been cancelled
Run Test / ${{ matrix.config.name }} (map[arch:x64 build-system:make diet-build:OFF enable-asan:OFF name:ubuntu-22.04 x64 make os:ubuntu-22.04]) (push) Has been cancelled
Run Test / ${{ matrix.config.name }} (map[arch:x64 name:windows x64 MSVC 64bit os:windows-latest platform:windows python-arch:x64 python-version:3.9]) (push) Has been cancelled
Run clang-tidy / clang-tidy (push) Has been cancelled
RELEASE BUILD - PyPI 📦 Distribution / Build wheels on ${{ matrix.os }} (macos-latest) (push) Has been cancelled
RELEASE BUILD - PyPI 📦 Distribution / Build wheels on ${{ matrix.os }} (ubuntu-latest) (push) Has been cancelled
RELEASE BUILD - PyPI 📦 Distribution / Build wheels on ${{ matrix.os }} (windows-latest) (push) Has been cancelled
RELEASE BUILD - PyPI 📦 Distribution / Make SDist (push) Has been cancelled
Python Package CI / build (macOS-14, 3.12) (push) Has been cancelled
Python Package CI / build (macOS-14, 3.8) (push) Has been cancelled
Python Package CI / build (ubuntu-24.04, 3.12) (push) Has been cancelled
Python Package CI / build (ubuntu-24.04, 3.8) (push) Has been cancelled
Python Package CI / build (windows-2022, 3.12) (push) Has been cancelled
Python Package CI / build (windows-2022, 3.8) (push) Has been cancelled
RELEASE BUILD - PyPI 📦 Distribution / publish (push) Has been cancelled
Coverity Scan / latest (push) Has been cancelled

This commit is contained in:
Rot127 2024-10-06 00:45:13 +00:00 committed by GitHub
parent 5bd05e3424
commit 52b54ee32d
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
12 changed files with 46 additions and 40 deletions

View File

@ -24,6 +24,9 @@ concurrency:
env: env:
CI: true CI: true
UBSAN_OPTIONS: "halt_on_error=1:abort_on_error=1:print_summary=1:print_stacktrace=1"
ASAN_OPTIONS: "halt_on_error=1:abort_on_error=1:print_summary=1:print_stacktrace=1"
LSAN_OPTIONS: "halt_on_error=1:abort_on_error=1:print_summary=1:print_stacktrace=1"
jobs: jobs:
Linux: Linux:
@ -86,10 +89,10 @@ jobs:
mkdir build && cd build mkdir build && cd build
# build static library # build static library
cmake -DCAPSTONE_INSTALL=1 -DCMAKE_INSTALL_PREFIX=/usr -DENABLE_ASAN=${asan} -DCAPSTONE_BUILD_DIET=${diet_build} .. cmake -DCAPSTONE_INSTALL=1 -DCMAKE_INSTALL_PREFIX=/usr -DENABLE_ASAN=${asan} -DCAPSTONE_BUILD_DIET=${diet_build} ..
cmake --build . --config Release cmake --build . --config Debug
# build shared library # build shared library
cmake -DCAPSTONE_INSTALL=1 -DBUILD_SHARED_LIBS=1 -DCMAKE_INSTALL_PREFIX=/usr -DCAPSTONE_BUILD_CSTEST=ON -DENABLE_ASAN=${asan} .. cmake -DCAPSTONE_INSTALL=1 -DBUILD_SHARED_LIBS=1 -DCMAKE_INSTALL_PREFIX=/usr -DCAPSTONE_BUILD_CSTEST=ON -DENABLE_ASAN=${asan} ..
sudo cmake --build . --config Release --target install sudo cmake --build . --config Debug --target install
- name: Lower number of KASL randomized address bits - name: Lower number of KASL randomized address bits
run: | run: |

View File

@ -72,8 +72,8 @@ option(ENABLE_COVERAGE "Enable test coverage" OFF)
if (ENABLE_ASAN) if (ENABLE_ASAN)
message("Enabling ASAN") message("Enabling ASAN")
add_definitions(-DASAN_ENABLED) add_definitions(-DASAN_ENABLED)
add_compile_options(-fsanitize=address) add_compile_options(-fsanitize=address,undefined)
add_link_options(-fsanitize=address) add_link_options(-fsanitize=address,undefined)
endif() endif()
if (ENABLE_COVERAGE) if (ENABLE_COVERAGE)

View File

@ -330,7 +330,10 @@ void printInt32(SStream *O, int32_t val)
SStream_concat(O, "%" PRId32, val); SStream_concat(O, "%" PRId32, val);
} else { } else {
if (val < -HEX_THRESHOLD) { if (val < -HEX_THRESHOLD) {
SStream_concat(O, "-0x%" PRIx32, (uint32_t)-val); if (val == INT32_MIN)
SStream_concat(O, "-0x%" PRIx32, (uint32_t) INT32_MAX + 1);
else
SStream_concat(O, "-0x%" PRIx32, (int32_t)-val);
} else { } else {
SStream_concat(O, "-%" PRIu32, (uint32_t)-val); SStream_concat(O, "-%" PRIu32, (uint32_t)-val);
} }

View File

@ -441,9 +441,9 @@ static inline float AArch64_AM_getFPImmFloat(unsigned Imm)
{ {
// We expect an 8-bit binary encoding of a floating-point number here. // We expect an 8-bit binary encoding of a floating-point number here.
uint8_t Sign = (Imm >> 7) & 0x1; uint32_t Sign = (Imm >> 7) & 0x1;
uint8_t Exp = (Imm >> 4) & 0x7; uint32_t Exp = (Imm >> 4) & 0x7;
uint8_t Mantissa = Imm & 0xf; uint32_t Mantissa = Imm & 0xf;
// 8-bit FP IEEE Float Encoding // 8-bit FP IEEE Float Encoding
// abcd efgh aBbbbbbc defgh000 00000000 00000000 // abcd efgh aBbbbbbc defgh000 00000000 00000000

View File

@ -769,9 +769,9 @@ static inline float ARM_AM_getFPImmFloat(unsigned Imm)
{ {
// We expect an 8-bit binary encoding of a floating-point number here. // We expect an 8-bit binary encoding of a floating-point number here.
uint8_t Sign = (Imm >> 7) & 0x1; uint32_t Sign = (Imm >> 7) & 0x1;
uint8_t Exp = (Imm >> 4) & 0x7; uint32_t Exp = (Imm >> 4) & 0x7;
uint8_t Mantissa = Imm & 0xf; uint32_t Mantissa = Imm & 0xf;
// 8-bit FP IEEE Float Encoding // 8-bit FP IEEE Float Encoding
// abcd efgh aBbbbbbc defgh000 00000000 00000000 // abcd efgh aBbbbbbc defgh000 00000000 00000000

View File

@ -162,7 +162,7 @@ static int extract_16(unsigned word, bool wide)
/* Extract a 21 bit constant. */ /* Extract a 21 bit constant. */
static int extract_21(unsigned word) static int32_t extract_21(unsigned word)
{ {
int val; int val;
@ -177,14 +177,14 @@ static int extract_21(unsigned word)
val |= get_insn_field(word, 0, 4); val |= get_insn_field(word, 0, 4);
val <<= 2; val <<= 2;
val |= get_insn_field(word, 7, 8); val |= get_insn_field(word, 7, 8);
return SignExtend32(val, 21) << 11; return (uint32_t) SignExtend32(val, 21) << 11;
} }
/* Extract a 12 bit constant from branch instructions. */ /* Extract a 12 bit constant from branch instructions. */
static int extract_12(unsigned word) static int32_t extract_12(unsigned word)
{ {
return SignExtend32(get_insn_field(word, 19, 28) | return (uint32_t) SignExtend32(get_insn_field(word, 19, 28) |
get_insn_field(word, 29, 29) << 10 | get_insn_field(word, 29, 29) << 10 |
(word & 0x1) << 11, (word & 0x1) << 11,
12) 12)
@ -194,9 +194,9 @@ static int extract_12(unsigned word)
/* Extract a 17 bit constant from branch instructions, returning the /* Extract a 17 bit constant from branch instructions, returning the
19 bit signed value. */ 19 bit signed value. */
static int extract_17(unsigned word) static int32_t extract_17(unsigned word)
{ {
return SignExtend32(get_insn_field(word, 19, 28) | return (uint32_t) SignExtend32(get_insn_field(word, 19, 28) |
get_insn_field(word, 29, 29) << 10 | get_insn_field(word, 29, 29) << 10 |
get_insn_field(word, 11, 15) << 11 | get_insn_field(word, 11, 15) << 11 |
(word & 0x1) << 16, (word & 0x1) << 16,
@ -204,9 +204,9 @@ static int extract_17(unsigned word)
<< 2; << 2;
} }
static int extract_22(unsigned word) static int32_t extract_22(unsigned word)
{ {
return SignExtend32(get_insn_field(word, 19, 28) | return (uint32_t) SignExtend32(get_insn_field(word, 19, 28) |
get_insn_field(word, 29, 29) << 10 | get_insn_field(word, 29, 29) << 10 |
get_insn_field(word, 11, 15) << 11 | get_insn_field(word, 11, 15) << 11 |
get_insn_field(word, 6, 10) << 16 | get_insn_field(word, 6, 10) << 16 |

View File

@ -154,8 +154,8 @@ static DecodeStatus decodeImm8Operand(MCInst *Inst, uint64_t Imm,
static DecodeStatus decodeImm8_sh8Operand(MCInst *Inst, uint64_t Imm, static DecodeStatus decodeImm8_sh8Operand(MCInst *Inst, uint64_t Imm,
int64_t Address, const void *Decoder) int64_t Address, const void *Decoder)
{ {
CS_ASSERT(isUIntN(8, Imm) && "Invalid immediate"); CS_ASSERT(isUIntN(16, Imm) && "Invalid immediate");
MCOperand_CreateImm0(Inst, (SignExtend64((Imm << 8), 16))); MCOperand_CreateImm0(Inst, (SignExtend64((Imm), 16)));
return MCDisassembler_Success; return MCDisassembler_Success;
} }

View File

@ -127,13 +127,13 @@ static inline void printL32RTarget(MCInst *MI, int OpNum, SStream *O)
if (MCOperand_isImm(MC)) { if (MCOperand_isImm(MC)) {
int64_t Value = int64_t Value =
MCOperand_getImm(MCInst_getOperand(MI, (OpNum))); MCOperand_getImm(MCInst_getOperand(MI, (OpNum)));
int64_t InstrOff = OneExtend32(Value << 2, 14); int32_t InstrOff = (uint32_t)OneExtend32(Value, 16) << 2;
CS_ASSERT( CS_ASSERT(
(Value >= -262144 && Value <= -4) && (InstrOff >= -262144 && InstrOff <= -4) &&
"Invalid argument, value must be in ranges [-262144,-4]"); "Invalid argument, value must be in ranges [-262144,-4]");
SStream_concat0(O, ". "); SStream_concat0(O, ". ");
if (MI->csh->LITBASE & 0x1) { if (MI->csh->LITBASE & 0x1) {
Value = (int64_t)(MI->csh->LITBASE & 0x7ff) + InstrOff; Value = ((MI->csh->LITBASE & 0xfffff000) >> 12) + InstrOff;
} else { } else {
Value = (((int64_t)MI->address + 3) & ~0x3) + InstrOff; Value = (((int64_t)MI->address + 3) & ~0x3) + InstrOff;
} }

View File

@ -201,12 +201,12 @@ void Xtensa_add_cs_detail(MCInst *MI, xtensa_op_group op_group, va_list args)
case XTENSA_OP_GROUP_L32RTARGET: { case XTENSA_OP_GROUP_L32RTARGET: {
int64_t Value = int64_t Value =
MCOperand_getImm(MCInst_getOperand(MI, (op_num))); MCOperand_getImm(MCInst_getOperand(MI, (op_num)));
int64_t InstrOff = OneExtend32(Value << 2, 14); int32_t InstrOff = (uint32_t)OneExtend32(Value, 16) << 2;
CS_ASSERT( CS_ASSERT(
(Value >= -262144 && Value <= -4) && (InstrOff >= -262144 && InstrOff <= -4) &&
"Invalid argument, value must be in ranges [-262144,-4]"); "Invalid argument, value must be in ranges [-262144,-4]");
if (MI->csh->LITBASE & 0x1) { if (MI->csh->LITBASE & 0x1) {
Value = (int64_t)(MI->csh->LITBASE & 0x7ff) + InstrOff; Value = ((MI->csh->LITBASE & 0xfffff000) >> 12) + InstrOff;
} else { } else {
Value = (((int64_t)MI->address + 3) & ~0x3) + InstrOff; Value = (((int64_t)MI->address + 3) & ~0x3) + InstrOff;
} }

View File

@ -81,7 +81,7 @@ struct cs_struct {
const uint8_t *regsize_map; // map to register size (x86-only for now) const uint8_t *regsize_map; // map to register size (x86-only for now)
GetRegisterAccess_t reg_access; GetRegisterAccess_t reg_access;
struct insn_mnem *mnem_list; // linked list of customized instruction mnemonic struct insn_mnem *mnem_list; // linked list of customized instruction mnemonic
uint32_t LITBASE; uint32_t LITBASE; ///< The LITBASE register content. Bit 0 (LSB) indicatess if it is set. Bit[23:8] are the literal base address.
}; };
#define MAX_ARCH CS_ARCH_MAX #define MAX_ARCH CS_ARCH_MAX

View File

@ -56,7 +56,7 @@ test_cases:
options: [ "xtensa" ] options: [ "xtensa" ]
expected: expected:
insns: insns:
- asm_text: "addmi a1, a2, 0" - asm_text: "addmi a1, a2, 0x7f00"
- -
input: input:

View File

@ -59,23 +59,23 @@ static void test()
size_t count = 0; size_t count = 0;
count = cs_disasm(handle, (const uint8_t *)DATA, sizeof(DATA) - 1, count = cs_disasm(handle, (const uint8_t *)DATA, sizeof(DATA) - 1,
0x10000, 2, &insn); 0x100000, 2, &insn);
// 1. Print out the instruction in default setup. // 1. Print out the instruction in default setup.
printf("Disassemble xtensa code with PC=0x10000\n"); printf("Disassemble xtensa code with PC=0x100000\n");
check_insn(insn, "l32r", "a1, . 0xc000"); check_insn(insn, "l32r", "a1, . 0xc0000");
check_insn(insn + 1, "l32r", "a1, . 0x10000"); check_insn(insn + 1, "l32r", "a1, . 0x100000");
print_insn(insn, count); print_insn(insn, count);
// Customized mnemonic JNE to JNZ using CS_OPT_LITBASE option // Customized mnemonic JNE to JNZ using CS_OPT_LITBASE option
printf("\nNow customize engine to change LITBASA to 0xff001\n"); printf("\nNow customize engine to change LITBASE to 0xfffff001\n");
cs_option(handle, CS_OPT_LITBASE, (size_t)0xff001); cs_option(handle, CS_OPT_LITBASE, (size_t)0xfffff001);
count = cs_disasm(handle, (const uint8_t *)DATA, sizeof(DATA) - 1, count = cs_disasm(handle, (const uint8_t *)DATA, sizeof(DATA) - 1,
0x10000, 2, &insn); 0x100000, 2, &insn);
// 2. Now print out the instruction in newly customized setup. // 2. Now print out the instruction in newly customized setup.
check_insn(insn, "l32r", "a1, . -0x3fff"); check_insn(insn, "l32r", "a1, . 0xbffff");
check_insn(insn + 1, "l32r", "a1, . -3"); check_insn(insn + 1, "l32r", "a1, . 0xffffb");
print_insn(insn, count); print_insn(insn, count);
// Done // Done