Skip to content
Closed
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
2 changes: 1 addition & 1 deletion arch/Xtensa/XtensaDisassembler.c
Original file line number Diff line number Diff line change
Expand Up @@ -788,7 +788,7 @@ static DecodeStatus decodeOffset_16_16Operand(MCInst *Inst, uint64_t Imm,
int64_t Address,
const void *Decoder)
{
CS_ASSERT_RET_VAL(isIntN(Imm, 8) && "Invalid immediate",
CS_ASSERT_RET_VAL(isIntN(8, Imm) && "Invalid immediate",
MCDisassembler_Fail);
if ((Imm & 0xf) != 0)
MCOperand_CreateImm0(Inst, (Imm << 4));
Expand Down
24 changes: 24 additions & 0 deletions tests/integration/test_poc.c
Original file line number Diff line number Diff line change
Expand Up @@ -130,12 +130,36 @@ static void test_ub_shift_sh_dsp_p(void)
return;
}

/// Swapped isIntN() arguments in Xtensa decodeOffset_16_16Operand. The
/// decoded immediate was passed as the bit width, so isIntN(Imm, 8)
/// shifted by Imm - 1. Small Imm values make Imm - 1 wrap to a huge
/// unsigned shift count and the signed shift/negation is UB.
static void test_ub_isintn_xtensa_offset(void)
{
static const uint8_t code[] = {
0x07, 0x75, 0x5d, 0xce, 0x50, 0x2b, 0x87
};

csh handle;
if (cs_open(CS_ARCH_XTENSA, CS_MODE_LITTLE_ENDIAN, &handle) !=
CS_ERR_OK)
return;
cs_option(handle, CS_OPT_DETAIL, CS_OPT_ON);

cs_insn *insn = NULL;
size_t count = cs_disasm(handle, code, sizeof(code), 0x1000, 0, &insn);
cs_free(insn, count);
cs_close(&handle);
return;
}

int main()
{
test_overflow_cs_insn_bytes();
test_overflow_cs_insn_bytes_iter();
test_overflow_set_reg_mem_n();
test_ub_shift_sh_dsp_p();
test_ub_isintn_xtensa_offset();

return 0;
}
Loading