From d1c1d7d7ee943aca2731b0b9bd344d8e1727b4d2 Mon Sep 17 00:00:00 2001 From: Kuan-Wei Chiu Date: Tue, 9 Jan 2024 05:24:51 +0800 Subject: [PATCH] Fix signed integer overflow in RV32M The current implementation of the mul instruction does not guard against integer overflow, potentially leading to undefined behavior. Cast the operands to int64_t before performing the multiplication to ensure that the result can be accommodated without overflow. The lower 32 bits of the product are then extracted, preserving the correct uint32_t type. --- riscv.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/riscv.c b/riscv.c index 36ccfa4..3c65a1b 100644 --- a/riscv.c +++ b/riscv.c @@ -594,8 +594,11 @@ static uint32_t op_mul(uint32_t insn, uint32_t a, uint32_t b) { /* TODO: Test ifunc7 zeros */ switch (decode_func3(insn)) { - case 0b000: /* MUL */ - return a * b; + case 0b000: { /* MUL */ + const int64_t _a = (int32_t) a; + const int64_t _b = (int32_t) b; + return ((uint64_t) (_a * _b)) & ((1ULL << 32) - 1); + } case 0b001: { /* MULH */ const int64_t _a = (int32_t) a; const int64_t _b = (int32_t) b;