From d2557e3873d4bf0ba0f01b8f16f780d8b80722f9 Mon Sep 17 00:00:00 2001 From: Inphi Date: Wed, 23 Oct 2024 14:37:28 -0700 Subject: [PATCH] cannon: Robust div by zero tests (#12600) --- cannon/mipsevm/exec/mips_instructions.go | 6 ++++++ cannon/mipsevm/tests/evm_common_test.go | 20 ++++++++++---------- 2 files changed, 16 insertions(+), 10 deletions(-) diff --git a/cannon/mipsevm/exec/mips_instructions.go b/cannon/mipsevm/exec/mips_instructions.go index af7b988c15849..1bf3849c4e3f9 100644 --- a/cannon/mipsevm/exec/mips_instructions.go +++ b/cannon/mipsevm/exec/mips_instructions.go @@ -500,9 +500,15 @@ func HandleHiLo(cpu *mipsevm.CpuScalars, registers *[32]Word, fun uint32, rs Wor cpu.HI = SignExtend(Word(acc>>32), 32) cpu.LO = SignExtend(Word(uint32(acc)), 32) case 0x1a: // div + if rt == 0 { + panic("instruction divide by zero") + } cpu.HI = SignExtend(Word(int32(rs)%int32(rt)), 32) cpu.LO = SignExtend(Word(int32(rs)/int32(rt)), 32) case 0x1b: // divu + if rt == 0 { + panic("instruction divide by zero") + } cpu.HI = SignExtend(Word(uint32(rs)%uint32(rt)), 32) cpu.LO = SignExtend(Word(uint32(rs)/uint32(rt)), 32) case 0x14: // dsllv diff --git a/cannon/mipsevm/tests/evm_common_test.go b/cannon/mipsevm/tests/evm_common_test.go index e204a0d96e9dc..c9dfd2f096343 100644 --- a/cannon/mipsevm/tests/evm_common_test.go +++ b/cannon/mipsevm/tests/evm_common_test.go @@ -450,16 +450,16 @@ func TestEVMSingleStep_MulDiv(t *testing.T) { expectLo Word expectRes Word rdReg uint32 - expectRevert bool + expectRevert string errMsg string }{ - {name: "mul", funct: uint32(0x2), rs: Word(5), rt: Word(2), opcode: uint32(28), rdReg: uint32(0x8), expectRes: Word(10), expectRevert: false}, // mul t0, t1, t2 - {name: "mult", funct: uint32(0x18), rs: Word(0x0F_FF_00_00), rt: Word(100), rdReg: uint32(0x0), opcode: uint32(0), expectHi: Word(0x6), expectLo: Word(0x3F_9C_00_00), expectRevert: false}, // mult t1, t2 - {name: "multu", funct: uint32(0x19), rs: Word(0x0F_FF_00_00), rt: Word(100), rdReg: uint32(0x0), opcode: uint32(0), expectHi: Word(0x6), expectLo: Word(0x3F_9C_00_00), expectRevert: false}, // multu t1, t2 - {name: "div", funct: uint32(0x1a), rs: Word(5), rt: Word(2), rdReg: uint32(0x0), opcode: uint32(0), expectHi: Word(1), expectLo: Word(2), expectRevert: false}, // div t1, t2 - {name: "div by zero", funct: uint32(0x1a), rs: Word(5), rt: Word(0), rdReg: uint32(0x0), opcode: uint32(0), expectRevert: true, errMsg: "MIPS: division by zero"}, // div t1, t2 - {name: "divu", funct: uint32(0x1b), rs: Word(5), rt: Word(2), rdReg: uint32(0x0), opcode: uint32(0), expectHi: Word(1), expectLo: Word(2), expectRevert: false}, // divu t1, t2 - {name: "divu by zero", funct: uint32(0x1b), rs: Word(5), rt: Word(0), rdReg: uint32(0x0), opcode: uint32(0), expectRevert: true, errMsg: "MIPS: division by zero"}, // divu t1, t2 + {name: "mul", funct: uint32(0x2), rs: Word(5), rt: Word(2), opcode: uint32(28), rdReg: uint32(0x8), expectRes: Word(10)}, // mul t0, t1, t2 + {name: "mult", funct: uint32(0x18), rs: Word(0x0F_FF_00_00), rt: Word(100), rdReg: uint32(0x0), opcode: uint32(0), expectHi: Word(0x6), expectLo: Word(0x3F_9C_00_00)}, // mult t1, t2 + {name: "multu", funct: uint32(0x19), rs: Word(0x0F_FF_00_00), rt: Word(100), rdReg: uint32(0x0), opcode: uint32(0), expectHi: Word(0x6), expectLo: Word(0x3F_9C_00_00)}, // multu t1, t2 + {name: "div", funct: uint32(0x1a), rs: Word(5), rt: Word(2), rdReg: uint32(0x0), opcode: uint32(0), expectHi: Word(1), expectLo: Word(2)}, // div t1, t2 + {name: "div by zero", funct: uint32(0x1a), rs: Word(5), rt: Word(0), rdReg: uint32(0x0), opcode: uint32(0), expectRevert: "instruction divide by zero", errMsg: "MIPS: division by zero"}, // div t1, t2 + {name: "divu", funct: uint32(0x1b), rs: Word(5), rt: Word(2), rdReg: uint32(0x0), opcode: uint32(0), expectHi: Word(1), expectLo: Word(2)}, // divu t1, t2 + {name: "divu by zero", funct: uint32(0x1b), rs: Word(5), rt: Word(0), rdReg: uint32(0x0), opcode: uint32(0), expectRevert: "instruction divide by zero", errMsg: "MIPS: division by zero"}, // divu t1, t2 } for _, v := range versions { @@ -477,9 +477,9 @@ func TestEVMSingleStep_MulDiv(t *testing.T) { state.GetRegistersRef()[baseReg] = tt.rs state.GetMemory().SetUint32(0, insn) - if tt.expectRevert { + if tt.expectRevert != "" { proofData := v.ProofGenerator(t, goVm.GetState()) - require.Panics(t, func() { + require.PanicsWithValue(t, tt.expectRevert, func() { _, _ = goVm.Step( false) })