Skip to content

Commit

Permalink
Merge pull request #19348 from LiangMa/overflowPR
Browse files Browse the repository at this point in the history
core/vm: Correct the Memory Gas Overflow condition
  • Loading branch information
karalabe authored Apr 1, 2019
2 parents cd79bc6 + 9294b8f commit 92faf1b
Show file tree
Hide file tree
Showing 2 changed files with 21 additions and 22 deletions.
16 changes: 6 additions & 10 deletions core/vm/gas_table.go
Original file line number Diff line number Diff line change
Expand Up @@ -25,21 +25,17 @@ import (
// memoryGasCost calculates the quadratic gas for memory expansion. It does so
// only for the memory region that is expanded, not the total memory.
func memoryGasCost(mem *Memory, newMemSize uint64) (uint64, error) {

if newMemSize == 0 {
return 0, nil
}
// The maximum that will fit in a uint64 is max_word_count - 1
// anything above that will result in an overflow.
// Additionally, a newMemSize which results in a
// newMemSizeWords larger than 0x7ffffffff will cause the square operation
// to overflow.
// The constant 0xffffffffe0 is the highest number that can be used without
// overflowing the gas calculation
if newMemSize > 0xffffffffe0 {
// The maximum that will fit in a uint64 is max_word_count - 1. Anything above
// that will result in an overflow. Additionally, a newMemSize which results in
// a newMemSizeWords larger than 0xFFFFFFFF will cause the square operation to
// overflow. The constant 0x1FFFFFFFE0 is the highest number that can be used
// without overflowing the gas calculation.
if newMemSize > 0x1FFFFFFFE0 {
return 0, errGasUintOverflow
}

newMemSizeWords := toWordSize(newMemSize)
newMemSize = newMemSizeWords * 32

Expand Down
27 changes: 15 additions & 12 deletions core/vm/gas_table_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,18 +19,21 @@ package vm
import "testing"

func TestMemoryGasCost(t *testing.T) {
//size := uint64(math.MaxUint64 - 64)
size := uint64(0xffffffffe0)
v, err := memoryGasCost(&Memory{}, size)
if err != nil {
t.Error("didn't expect error:", err)
tests := []struct {
size uint64
cost uint64
overflow bool
}{
{0x1fffffffe0, 36028809887088637, false},
{0x1fffffffe1, 0, true},
}
if v != 36028899963961341 {
t.Errorf("Expected: 36028899963961341, got %d", v)
}

_, err = memoryGasCost(&Memory{}, size+1)
if err == nil {
t.Error("expected error")
for i, tt := range tests {
v, err := memoryGasCost(&Memory{}, tt.size)
if (err == errGasUintOverflow) != tt.overflow {
t.Errorf("test %d: overflow mismatch: have %v, want %v", i, err == errGasUintOverflow, tt.overflow)
}
if v != tt.cost {
t.Errorf("test %d: gas cost mismatch: have %v, want %v", i, v, tt.cost)
}
}
}

0 comments on commit 92faf1b

Please sign in to comment.