From cd949f624411010baec2cdb1e45aef74f1cb8110 Mon Sep 17 00:00:00 2001 From: bibi samina Date: Wed, 8 Jul 2026 14:08:17 +0530 Subject: [PATCH] m68k: fix undefined abs() of INT32_MIN displacement in printer --- arch/M68K/M68KInstPrinter.c | 13 ++++++++++--- tests/integration/test_poc.c | 21 +++++++++++++++++++++ 2 files changed, 31 insertions(+), 3 deletions(-) diff --git a/arch/M68K/M68KInstPrinter.c b/arch/M68K/M68KInstPrinter.c index 980a7231c8..3f1fac6b17 100644 --- a/arch/M68K/M68KInstPrinter.c +++ b/arch/M68K/M68KInstPrinter.c @@ -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) { @@ -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, "("); @@ -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) { @@ -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, ")"); diff --git a/tests/integration/test_poc.c b/tests/integration/test_poc.c index f461de4f47..a29497d615 100644 --- a/tests/integration/test_poc.c +++ b/tests/integration/test_poc.c @@ -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; }