Skip to content

Commit

Permalink
Merge pull request #100 from ethereum-optimism/feature/mininny/audit-3
Browse files Browse the repository at this point in the history
Use only the lowest 32 bit of input for 32 bit division operations
  • Loading branch information
mininny authored Jan 15, 2025
2 parents 07b004f + c208cb5 commit 45c520d
Show file tree
Hide file tree
Showing 4 changed files with 22 additions and 3 deletions.
2 changes: 1 addition & 1 deletion rvgo/fast/vm.go
Original file line number Diff line number Diff line change
Expand Up @@ -772,7 +772,7 @@ func (inst *InstrumentedState) riscvStep() (outErr error) {
setPC(add64(pc, toU64(4)))
case 0x3B: // 011_1011: register arithmetic and logic in 32 bits
rs1Value := getRegister(rs1)
rs2Value := getRegister(rs2)
rs2Value := and64(getRegister(rs2), u32Mask())
var rdValue U64
switch funct7 {
case 1: // RV M extension
Expand Down
2 changes: 1 addition & 1 deletion rvgo/slow/vm.go
Original file line number Diff line number Diff line change
Expand Up @@ -956,7 +956,7 @@ func Step(calldata []byte, po PreimageOracle) (stateHash common.Hash, outErr err
setPC(add64(pc, toU64(4)))
case 0x3B: // 011_1011: register arithmetic and logic in 32 bits
rs1Value := getRegister(rs1)
rs2Value := getRegister(rs2)
rs2Value := and64(getRegister(rs2), u32Mask())
var rdValue U64
switch funct7.val() {
case 1: // RV M extension
Expand Down
2 changes: 1 addition & 1 deletion rvsol/src/RISCV.sol
Original file line number Diff line number Diff line change
Expand Up @@ -1419,7 +1419,7 @@ contract RISCV is IBigStepper {
case 0x3B {
// 011_1011: register arithmetic and logic in 32 bits
let rs1Value := getRegister(rs1)
let rs2Value := getRegister(rs2)
let rs2Value := and64(getRegister(rs2), u32Mask())
let rdValue := 0
switch funct7
case 1 {
Expand Down
19 changes: 19 additions & 0 deletions rvsol/test/RISCV.t.sol
Original file line number Diff line number Diff line change
Expand Up @@ -607,6 +607,25 @@ contract RISCV_Test is CommonTest {
assertEq(postState, outputState(expect), "unexpected post state");
}

function test_remw_by_zero_succeeds() public {
uint32 insn = encodeRType(0x3b, 27, 6, 22, 21, 1); // remw x27, x22, x21
(State memory state, bytes memory proof) = constructRISCVState(0, insn);
state.registers[22] = 0x100f00000; //bits > 32 should be ignored
state.registers[21] = 0x200000000; // bits > 32 should be ignored, resulting in division by zero
bytes memory encodedState = encodeState(state);

State memory expect;
expect.memRoot = state.memRoot;
expect.pc = state.pc + 4;
expect.step = state.step + 1;
expect.registers[27] = 0x00f00000; // should return original dividend (least 32 bits)
expect.registers[22] = state.registers[22];
expect.registers[21] = state.registers[21];

bytes32 postState = riscv.step(encodedState, proof, 0);
assertEq(postState, outputState(expect), "unexpected post state");
}

function test_remuw_succeeds() public {
uint32 insn = encodeRType(0x3b, 30, 7, 27, 9, 1); // remuw x30, x27, x9
(State memory state, bytes memory proof) = constructRISCVState(0, insn);
Expand Down

0 comments on commit 45c520d

Please sign in to comment.