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:
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:
Linux:
@ -86,10 +89,10 @@ jobs:
mkdir build && cd build
# build static library
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
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
run: |

View File

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

View File

@ -330,7 +330,10 @@ void printInt32(SStream *O, int32_t val)
SStream_concat(O, "%" PRId32, val);
} else {
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 {
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.
uint8_t Sign = (Imm >> 7) & 0x1;
uint8_t Exp = (Imm >> 4) & 0x7;
uint8_t Mantissa = Imm & 0xf;
uint32_t Sign = (Imm >> 7) & 0x1;
uint32_t Exp = (Imm >> 4) & 0x7;
uint32_t Mantissa = Imm & 0xf;
// 8-bit FP IEEE Float Encoding
// 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.
uint8_t Sign = (Imm >> 7) & 0x1;
uint8_t Exp = (Imm >> 4) & 0x7;
uint8_t Mantissa = Imm & 0xf;
uint32_t Sign = (Imm >> 7) & 0x1;
uint32_t Exp = (Imm >> 4) & 0x7;
uint32_t Mantissa = Imm & 0xf;
// 8-bit FP IEEE Float Encoding
// 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. */
static int extract_21(unsigned word)
static int32_t extract_21(unsigned word)
{
int val;
@ -177,14 +177,14 @@ static int extract_21(unsigned word)
val |= get_insn_field(word, 0, 4);
val <<= 2;
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. */
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 |
(word & 0x1) << 11,
12)
@ -194,9 +194,9 @@ static int extract_12(unsigned word)
/* Extract a 17 bit constant from branch instructions, returning the
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, 11, 15) << 11 |
(word & 0x1) << 16,
@ -204,9 +204,9 @@ static int extract_17(unsigned word)
<< 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, 11, 15) << 11 |
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,
int64_t Address, const void *Decoder)
{
CS_ASSERT(isUIntN(8, Imm) && "Invalid immediate");
MCOperand_CreateImm0(Inst, (SignExtend64((Imm << 8), 16)));
CS_ASSERT(isUIntN(16, Imm) && "Invalid immediate");
MCOperand_CreateImm0(Inst, (SignExtend64((Imm), 16)));
return MCDisassembler_Success;
}

View File

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

View File

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

View File

@ -59,23 +59,23 @@ static void test()
size_t count = 0;
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.
printf("Disassemble xtensa code with PC=0x10000\n");
check_insn(insn, "l32r", "a1, . 0xc000");
check_insn(insn + 1, "l32r", "a1, . 0x10000");
printf("Disassemble xtensa code with PC=0x100000\n");
check_insn(insn, "l32r", "a1, . 0xc0000");
check_insn(insn + 1, "l32r", "a1, . 0x100000");
print_insn(insn, count);
// Customized mnemonic JNE to JNZ using CS_OPT_LITBASE option
printf("\nNow customize engine to change LITBASA to 0xff001\n");
cs_option(handle, CS_OPT_LITBASE, (size_t)0xff001);
printf("\nNow customize engine to change LITBASE to 0xfffff001\n");
cs_option(handle, CS_OPT_LITBASE, (size_t)0xfffff001);
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.
check_insn(insn, "l32r", "a1, . -0x3fff");
check_insn(insn + 1, "l32r", "a1, . -3");
check_insn(insn, "l32r", "a1, . 0xbffff");
check_insn(insn + 1, "l32r", "a1, . 0xffffb");
print_insn(insn, count);
// Done