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
13 changes: 10 additions & 3 deletions arch/M68K/M68KInstPrinter.c
Original file line number Diff line number Diff line change
Expand Up @@ -125,6 +125,13 @@ static const char *getRegName(m68k_reg reg)
return s_reg_names[(int)reg];
}

// abs() is undefined for INT32_MIN, which a 32-bit displacement can hold.
// Compute the magnitude via unsigned negation to stay well-defined.
static uint32_t disp_abs(int32_t disp)
{
return disp < 0 ? -(uint32_t)disp : (uint32_t)disp;
}

static void printRegbits(SStream *O, bool *need_sep, uint32_t data,
const char *prefix)
{
Expand Down Expand Up @@ -289,7 +296,7 @@ static void printBaseDisp(SStream *O, unsigned int pc, const cs_m68k_op *op)
} else if (op->mem.in_disp != 0) {
SStream_concat(O, "%s$%" PRIx32,
op->mem.in_disp >= 0 ? "" : "-",
abs(op->mem.in_disp));
disp_abs(op->mem.in_disp));
}

SStream_concat0(O, "(");
Expand Down Expand Up @@ -328,7 +335,7 @@ static void printMemIndirect(SStream *O, unsigned int pc, const cs_m68k_op *op)
} else if (op->mem.in_disp != 0) {
SStream_concat(O, "%s$%" PRIx32,
op->mem.in_disp >= 0 ? "" : "-",
abs(op->mem.in_disp));
disp_abs(op->mem.in_disp));
}

if (op->mem.base_reg != M68K_REG_INVALID) {
Expand All @@ -355,7 +362,7 @@ static void printMemIndirect(SStream *O, unsigned int pc, const cs_m68k_op *op)
if (op->mem.out_disp != 0) {
SStream_concat(O, ",%s%s$%" PRIx32, s_spacing,
op->mem.out_disp >= 0 ? "" : "-",
abs(op->mem.out_disp));
disp_abs(op->mem.out_disp));
}

SStream_concat0(O, ")");
Expand Down
21 changes: 21 additions & 0 deletions tests/integration/test_poc.c
Original file line number Diff line number Diff line change
Expand Up @@ -130,12 +130,33 @@ static void test_ub_shift_sh_dsp_p(void)
return;
}

/// A 32-bit outer displacement of INT32_MIN reaches abs() in the M68K
/// memory-indirect printer, whose negation of INT32_MIN is undefined.
static void test_ub_abs_m68k_disp(void)
{
static const uint8_t code[] = { 0x37, 0x37, 0x37, 0x37, 0x37, 0x17,
0x00, 0x1d, 0x80, 0x00, 0x00, 0x00 };

csh handle;
if (cs_open(CS_ARCH_M68K, CS_MODE_BIG_ENDIAN | CS_MODE_M68K_040,
&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_abs_m68k_disp();

return 0;
}
Loading