Skip to content

Commit dd7fe1b

Browse files
core/vm: fix modexp gas calculation (#32568)
fixes a bug in the gas calculation found by oss-fuzz
1 parent d68528c commit dd7fe1b

File tree

2 files changed

+35
-4
lines changed

2 files changed

+35
-4
lines changed

core/vm/contracts.go

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -469,12 +469,19 @@ func modexpIterationCount(expLen uint64, expHead uint256.Int, multiplier uint64)
469469

470470
// For large exponents (expLen > 32), add (expLen - 32) * multiplier
471471
if expLen > 32 {
472-
iterationCount = (expLen - 32) * multiplier
472+
carry, count := bits.Mul64(expLen-32, multiplier)
473+
if carry > 0 {
474+
return math.MaxUint64
475+
}
476+
iterationCount = count
473477
}
474-
475478
// Add the MSB position - 1 if expHead is non-zero
476479
if bitLen := expHead.BitLen(); bitLen > 0 {
477-
iterationCount += uint64(bitLen - 1)
480+
count, carry := bits.Add64(iterationCount, uint64(bitLen-1), 0)
481+
if carry > 0 {
482+
return math.MaxUint64
483+
}
484+
iterationCount = count
478485
}
479486

480487
return max(iterationCount, 1)

core/vm/contracts_test.go

Lines changed: 25 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -118,7 +118,7 @@ func testPrecompiled(addr string, test precompiledTest, t *testing.T) {
118118
func testPrecompiledOOG(addr string, test precompiledTest, t *testing.T) {
119119
p := allPrecompiles[common.HexToAddress(addr)]
120120
in := common.Hex2Bytes(test.Input)
121-
gas := p.RequiredGas(in) - 1
121+
gas := test.Gas - 1
122122

123123
t.Run(fmt.Sprintf("%s-Gas=%d", test.Name, gas), func(t *testing.T) {
124124
_, _, err := RunPrecompiledContract(p, in, gas, nil)
@@ -257,6 +257,30 @@ func TestPrecompiledModExpOOG(t *testing.T) {
257257
for _, test := range modexpTests {
258258
testPrecompiledOOG("05", test, t)
259259
}
260+
modexpTestsEIP2565, err := loadJson("modexp_eip2565")
261+
if err != nil {
262+
t.Fatal(err)
263+
}
264+
for _, test := range modexpTestsEIP2565 {
265+
testPrecompiledOOG("f5", test, t)
266+
}
267+
modexpTestsEIP7883, err := loadJson("modexp_eip7883")
268+
if err != nil {
269+
t.Fatal(err)
270+
}
271+
for _, test := range modexpTestsEIP7883 {
272+
testPrecompiledOOG("f6", test, t)
273+
}
274+
gasCostTest := precompiledTest{
275+
Input: "000000000000000000000000000000000000000000000000000000000000082800000000000000000000000000000000000000000000000040000000000000090000000000000000000000000000000000000000000000000000000000000600000000adadadad00000000ff31ff00000006ffffffffffffffffffffffffffffffffffffffff0000000000000004ffffffffffffff0000000000000000000000000000000000000000d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0000001000200fefffeff01000100000000000000ffff01000100ffffffff01000100ffffffff0000050001000100fefffdff02000300ff000000000000012b000000000000090000000000000000000000000000000000000000000000000000ffffff000000000200fffffeff00000001000000000001000200fefffeff010001000000000000000000423034000000000011006161ffbf640053004f00ff00fffffffffffffff3ff00000000000f00002dffffffffff0000000000000000000061999999999999999999999999899961ffffffff0100010000000000000000000000000600000000adadadad00000000ffff00000006fffffdffffffffffffffffffffffffffffffffff0000000000000004ffffffffffffff000000000000000000000000000000000000000098000000966375726c2f66000030000000000011006161ffbf640053004f002d00000000a200000000000000ff1818183fffffffff3a6e756c6c2c22223a6e7500006c2000000000002d2d0000000000000000000144ccef0100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000080000000000000000fdff000000ff00290001000009000000000000000000000000000000000000000000000000a50004ff2800000000000000000000000000000000000000000000000001000000000000090000000000000000000000030000000000000000002b00000000000000000600000000adadadad00000000ffff00000006ffffffffffffffffffffffffffffffffffffffff0000000000000004ffffffffffffff0000000000000000000000000000000000000000d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d000000000717a1a001a1a1a1a1a1a000000121212121212121212121212121212121212121212d0d0d0d01212121212121212121212121212121212121212121212121212121212121212121212121212121212121212373800002d35373837346137346161610000000000000000d0d0d0d0d0d0d0d0002d3533321a1a000000d0d0d0d0d0d0d0d0d0d0d0d0d0d000000000717a1a001a1a1a1a1a1a000000121212121212121212121212121212121212121212d0d0d0d012121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121a1212121212121212000000000000000000000000d0d0d0d0d0d0d0d0002d3533321a1a0000000000000000000000003300000001000f5b00001100712c6eff9e61000000000061000000fbffff1a1a3a6e353900756c6c7d3b00000000009100002d35ff00600000000000000000002d3533321a1a1a1a3a6e353900756c6c7d3b000000000091373800002d3537383734613734616161d0d0d0d0d000000000717a1a001a1a1a1a1a1a000000121212121212121212121212121212121212121212d0d0d0d012121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121a1212121212121212000000000000000000000000d0d0d0d0d0d0d0d0002d3533321a1a0000000000000000000000003300000001000f5b00001100712c6eff9e61000000000061000000fbffff1a1a3a6e353900756c6c7d3b00000000009100002d35ff00600000000000000000002d3533321a1a1a1a3a6e353900756c6c7d3b000000000091373800002d353738373461373461616100000000000000000000000000000000000000000000000001000000000000090000000000000000000000030000000000000000002b00000000000000000600000000adadadad00000000ffff00000006ffffffffffffffffffffffffffffffffffffffff0000000000000004ffffffffffffff0000000000000000000000000000000000000000d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d000000000717a1a001a1a1a1a1a1a000000121212121212121212121212121212121212121212d0d0d0d01212121212121212121212121212121212121212121212121212121212121212121212121212121212121212373800002d35373837346137346161610000000000000000d0d0d0d0d0d0d0d0002d3533321a1a000000d0d0d0d0d0d0d0d0d0d0d0d0d0d000000000717a1a001a1a1a1a1a1a000000121212121212121212121212121212121212121212d0d0d0d012121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121a1212121212121212000000000000000000000000d0d0d0d0d0d0d0d0002d3533321a1a0000000000000000000000003300000001000f5b00001100712c6eff9e61000000000061000000fbffff1a1a3a6e353900756c6c7d3b00000000009100002d35ff00600000000000000000002d3533321a1a1a1a3a6e353900756c6c7d3b000000000091373800002d3537383734613734616161d0d0d0d0d000000000717a1a001a1a1a1a1a1a0000001212121212121212121212121212121212121212000000000000003300000001000f5b00001100712c6eff9e61000000000061000000fbffff1a1a3a6e353900756c6c7d3b00000000009100002d35ff00600000000000000000002d3533321a1a1a1a3a6e353900756c6c7d3b000000000091373800002d3537383734613734616161",
276+
Expected: "000000000000000000000000000000000000000000000000",
277+
Name: "oss_fuzz_gas_calc",
278+
Gas: 18446744073709551615,
279+
NoBenchmark: false,
280+
}
281+
testPrecompiledOOG("05", gasCostTest, t)
282+
testPrecompiledOOG("f5", gasCostTest, t)
283+
testPrecompiledOOG("f6", gasCostTest, t)
260284
}
261285

262286
// Tests the sample inputs from the elliptic curve scalar multiplication EIP 213.

0 commit comments

Comments
 (0)