tests/fuzzers: update fuzzers to be based on go-native fuzzing (#28352)

This change modifies the fuzzers to use the native golang fuzzing framework instead of go-fuzz
This commit is contained in:
Marius van der Wijden
2023-10-18 15:01:16 +02:00
committed by GitHub
parent da55b23d21
commit d10a2f6ab7
38 changed files with 639 additions and 560 deletions
-170
View File
@@ -1,170 +0,0 @@
// Copyright 2020 The go-ethereum Authors
// This file is part of the go-ethereum library.
//
// The go-ethereum library is free software: you can redistribute it and/or modify
// it under the terms of the GNU Lesser General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// The go-ethereum library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public License
// along with the go-ethereum library. If not, see <http://www.gnu.org/licenses/>.
package abi
import (
"fmt"
"reflect"
"strings"
"github.com/ethereum/go-ethereum/accounts/abi"
fuzz "github.com/google/gofuzz"
)
var (
names = []string{"_name", "name", "NAME", "name_", "__", "_name_", "n"}
stateMut = []string{"", "pure", "view", "payable"}
stateMutabilites = []*string{&stateMut[0], &stateMut[1], &stateMut[2], &stateMut[3]}
pays = []string{"", "true", "false"}
payables = []*string{&pays[0], &pays[1]}
vNames = []string{"a", "b", "c", "d", "e", "f", "g"}
varNames = append(vNames, names...)
varTypes = []string{"bool", "address", "bytes", "string",
"uint8", "int8", "uint8", "int8", "uint16", "int16",
"uint24", "int24", "uint32", "int32", "uint40", "int40", "uint48", "int48", "uint56", "int56",
"uint64", "int64", "uint72", "int72", "uint80", "int80", "uint88", "int88", "uint96", "int96",
"uint104", "int104", "uint112", "int112", "uint120", "int120", "uint128", "int128", "uint136", "int136",
"uint144", "int144", "uint152", "int152", "uint160", "int160", "uint168", "int168", "uint176", "int176",
"uint184", "int184", "uint192", "int192", "uint200", "int200", "uint208", "int208", "uint216", "int216",
"uint224", "int224", "uint232", "int232", "uint240", "int240", "uint248", "int248", "uint256", "int256",
"bytes1", "bytes2", "bytes3", "bytes4", "bytes5", "bytes6", "bytes7", "bytes8", "bytes9", "bytes10", "bytes11",
"bytes12", "bytes13", "bytes14", "bytes15", "bytes16", "bytes17", "bytes18", "bytes19", "bytes20", "bytes21",
"bytes22", "bytes23", "bytes24", "bytes25", "bytes26", "bytes27", "bytes28", "bytes29", "bytes30", "bytes31",
"bytes32", "bytes"}
)
func unpackPack(abi abi.ABI, method string, input []byte) ([]interface{}, bool) {
if out, err := abi.Unpack(method, input); err == nil {
_, err := abi.Pack(method, out...)
if err != nil {
// We have some false positives as we can unpack these type successfully, but not pack them
if err.Error() == "abi: cannot use []uint8 as type [0]int8 as argument" ||
err.Error() == "abi: cannot use uint8 as type int8 as argument" {
return out, false
}
panic(err)
}
return out, true
}
return nil, false
}
func packUnpack(abi abi.ABI, method string, input *[]interface{}) bool {
if packed, err := abi.Pack(method, input); err == nil {
outptr := reflect.New(reflect.TypeOf(input))
err := abi.UnpackIntoInterface(outptr.Interface(), method, packed)
if err != nil {
panic(err)
}
out := outptr.Elem().Interface()
if !reflect.DeepEqual(input, out) {
panic(fmt.Sprintf("unpackPack is not equal, \ninput : %x\noutput: %x", input, out))
}
return true
}
return false
}
type args struct {
name string
typ string
}
func createABI(name string, stateMutability, payable *string, inputs []args) (abi.ABI, error) {
sig := fmt.Sprintf(`[{ "type" : "function", "name" : "%v" `, name)
if stateMutability != nil {
sig += fmt.Sprintf(`, "stateMutability": "%v" `, *stateMutability)
}
if payable != nil {
sig += fmt.Sprintf(`, "payable": %v `, *payable)
}
if len(inputs) > 0 {
sig += `, "inputs" : [ {`
for i, inp := range inputs {
sig += fmt.Sprintf(`"name" : "%v", "type" : "%v" `, inp.name, inp.typ)
if i+1 < len(inputs) {
sig += ","
}
}
sig += "} ]"
sig += `, "outputs" : [ {`
for i, inp := range inputs {
sig += fmt.Sprintf(`"name" : "%v", "type" : "%v" `, inp.name, inp.typ)
if i+1 < len(inputs) {
sig += ","
}
}
sig += "} ]"
}
sig += `}]`
return abi.JSON(strings.NewReader(sig))
}
func runFuzzer(input []byte) int {
good := false
fuzzer := fuzz.NewFromGoFuzz(input)
name := names[getUInt(fuzzer)%len(names)]
stateM := stateMutabilites[getUInt(fuzzer)%len(stateMutabilites)]
payable := payables[getUInt(fuzzer)%len(payables)]
maxLen := 5
for k := 1; k < maxLen; k++ {
var arg []args
for i := k; i > 0; i-- {
argName := varNames[i]
argTyp := varTypes[getUInt(fuzzer)%len(varTypes)]
if getUInt(fuzzer)%10 == 0 {
argTyp += "[]"
} else if getUInt(fuzzer)%10 == 0 {
arrayArgs := getUInt(fuzzer)%30 + 1
argTyp += fmt.Sprintf("[%d]", arrayArgs)
}
arg = append(arg, args{
name: argName,
typ: argTyp,
})
}
abi, err := createABI(name, stateM, payable, arg)
if err != nil {
continue
}
structs, b := unpackPack(abi, name, input)
c := packUnpack(abi, name, &structs)
good = good || b || c
}
if good {
return 1
}
return 0
}
func Fuzz(input []byte) int {
return runFuzzer(input)
}
func getUInt(fuzzer *fuzz.Fuzzer) int {
var i int
fuzzer.Fuzz(&i)
if i < 0 {
i = -i
if i < 0 {
return 0
}
}
return i
}
+149 -11
View File
@@ -17,7 +17,13 @@
package abi
import (
"fmt"
"reflect"
"strings"
"testing"
"github.com/ethereum/go-ethereum/accounts/abi"
fuzz "github.com/google/gofuzz"
)
// TestReplicate can be used to replicate crashers from the fuzzing tests.
@@ -25,19 +31,151 @@ import (
func TestReplicate(t *testing.T) {
testString := "\x20\x20\x20\x20\x20\x20\x20\x20\x80\x00\x00\x00\x20\x20\x20\x20\x00"
data := []byte(testString)
runFuzzer(data)
fuzzAbi(data)
}
// TestGenerateCorpus can be used to add corpus for the fuzzer.
// Just replace corpusHex with the hexEncoded output you want to add to the fuzzer.
func TestGenerateCorpus(t *testing.T) {
/*
corpusHex := "ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"
data := common.FromHex(corpusHex)
checksum := sha1.Sum(data)
outf := fmt.Sprintf("corpus/%x", checksum)
if err := os.WriteFile(outf, data, 0777); err != nil {
func Fuzz(f *testing.F) {
f.Fuzz(func(t *testing.T, data []byte) {
fuzzAbi(data)
})
}
var (
names = []string{"_name", "name", "NAME", "name_", "__", "_name_", "n"}
stateMut = []string{"", "pure", "view", "payable"}
stateMutabilites = []*string{&stateMut[0], &stateMut[1], &stateMut[2], &stateMut[3]}
pays = []string{"", "true", "false"}
payables = []*string{&pays[0], &pays[1]}
vNames = []string{"a", "b", "c", "d", "e", "f", "g"}
varNames = append(vNames, names...)
varTypes = []string{"bool", "address", "bytes", "string",
"uint8", "int8", "uint8", "int8", "uint16", "int16",
"uint24", "int24", "uint32", "int32", "uint40", "int40", "uint48", "int48", "uint56", "int56",
"uint64", "int64", "uint72", "int72", "uint80", "int80", "uint88", "int88", "uint96", "int96",
"uint104", "int104", "uint112", "int112", "uint120", "int120", "uint128", "int128", "uint136", "int136",
"uint144", "int144", "uint152", "int152", "uint160", "int160", "uint168", "int168", "uint176", "int176",
"uint184", "int184", "uint192", "int192", "uint200", "int200", "uint208", "int208", "uint216", "int216",
"uint224", "int224", "uint232", "int232", "uint240", "int240", "uint248", "int248", "uint256", "int256",
"bytes1", "bytes2", "bytes3", "bytes4", "bytes5", "bytes6", "bytes7", "bytes8", "bytes9", "bytes10", "bytes11",
"bytes12", "bytes13", "bytes14", "bytes15", "bytes16", "bytes17", "bytes18", "bytes19", "bytes20", "bytes21",
"bytes22", "bytes23", "bytes24", "bytes25", "bytes26", "bytes27", "bytes28", "bytes29", "bytes30", "bytes31",
"bytes32", "bytes"}
)
func unpackPack(abi abi.ABI, method string, input []byte) ([]interface{}, bool) {
if out, err := abi.Unpack(method, input); err == nil {
_, err := abi.Pack(method, out...)
if err != nil {
// We have some false positives as we can unpack these type successfully, but not pack them
if err.Error() == "abi: cannot use []uint8 as type [0]int8 as argument" ||
err.Error() == "abi: cannot use uint8 as type int8 as argument" {
return out, false
}
panic(err)
}
*/
return out, true
}
return nil, false
}
func packUnpack(abi abi.ABI, method string, input *[]interface{}) bool {
if packed, err := abi.Pack(method, input); err == nil {
outptr := reflect.New(reflect.TypeOf(input))
err := abi.UnpackIntoInterface(outptr.Interface(), method, packed)
if err != nil {
panic(err)
}
out := outptr.Elem().Interface()
if !reflect.DeepEqual(input, out) {
panic(fmt.Sprintf("unpackPack is not equal, \ninput : %x\noutput: %x", input, out))
}
return true
}
return false
}
type args struct {
name string
typ string
}
func createABI(name string, stateMutability, payable *string, inputs []args) (abi.ABI, error) {
sig := fmt.Sprintf(`[{ "type" : "function", "name" : "%v" `, name)
if stateMutability != nil {
sig += fmt.Sprintf(`, "stateMutability": "%v" `, *stateMutability)
}
if payable != nil {
sig += fmt.Sprintf(`, "payable": %v `, *payable)
}
if len(inputs) > 0 {
sig += `, "inputs" : [ {`
for i, inp := range inputs {
sig += fmt.Sprintf(`"name" : "%v", "type" : "%v" `, inp.name, inp.typ)
if i+1 < len(inputs) {
sig += ","
}
}
sig += "} ]"
sig += `, "outputs" : [ {`
for i, inp := range inputs {
sig += fmt.Sprintf(`"name" : "%v", "type" : "%v" `, inp.name, inp.typ)
if i+1 < len(inputs) {
sig += ","
}
}
sig += "} ]"
}
sig += `}]`
return abi.JSON(strings.NewReader(sig))
}
func fuzzAbi(input []byte) int {
good := false
fuzzer := fuzz.NewFromGoFuzz(input)
name := names[getUInt(fuzzer)%len(names)]
stateM := stateMutabilites[getUInt(fuzzer)%len(stateMutabilites)]
payable := payables[getUInt(fuzzer)%len(payables)]
maxLen := 5
for k := 1; k < maxLen; k++ {
var arg []args
for i := k; i > 0; i-- {
argName := varNames[i]
argTyp := varTypes[getUInt(fuzzer)%len(varTypes)]
if getUInt(fuzzer)%10 == 0 {
argTyp += "[]"
} else if getUInt(fuzzer)%10 == 0 {
arrayArgs := getUInt(fuzzer)%30 + 1
argTyp += fmt.Sprintf("[%d]", arrayArgs)
}
arg = append(arg, args{
name: argName,
typ: argTyp,
})
}
abi, err := createABI(name, stateM, payable, arg)
if err != nil {
continue
}
structs, b := unpackPack(abi, name, input)
c := packUnpack(abi, name, &structs)
good = good || b || c
}
if good {
return 1
}
return 0
}
func getUInt(fuzzer *fuzz.Fuzzer) int {
var i int
fuzzer.Fuzz(&i)
if i < 0 {
i = -i
if i < 0 {
return 0
}
}
return i
}
@@ -1,4 +1,4 @@
// Copyright 2017 The go-ethereum Authors
// Copyright 2023 The go-ethereum Authors
// This file is part of the go-ethereum library.
//
// The go-ethereum library is free software: you can redistribute it and/or modify
@@ -18,38 +18,37 @@ package bitutil
import (
"bytes"
"testing"
"github.com/ethereum/go-ethereum/common/bitutil"
)
// Fuzz implements a go-fuzz fuzzer method to test various encoding method
// invocations.
func Fuzz(data []byte) int {
if len(data) == 0 {
return 0
}
if data[0]%2 == 0 {
return fuzzEncode(data[1:])
}
return fuzzDecode(data[1:])
func FuzzEncoder(f *testing.F) {
f.Fuzz(func(t *testing.T, data []byte) {
fuzzEncode(data)
})
}
func FuzzDecoder(f *testing.F) {
f.Fuzz(func(t *testing.T, data []byte) {
fuzzDecode(data)
})
}
// fuzzEncode implements a go-fuzz fuzzer method to test the bitset encoding and
// decoding algorithm.
func fuzzEncode(data []byte) int {
func fuzzEncode(data []byte) {
proc, _ := bitutil.DecompressBytes(bitutil.CompressBytes(data), len(data))
if !bytes.Equal(data, proc) {
panic("content mismatch")
}
return 1
}
// fuzzDecode implements a go-fuzz fuzzer method to test the bit decoding and
// reencoding algorithm.
func fuzzDecode(data []byte) int {
func fuzzDecode(data []byte) {
blob, err := bitutil.DecompressBytes(data, 1024)
if err != nil {
return 0
return
}
// re-compress it (it's OK if the re-compressed differs from the
// original - the first input may not have been compressed at all)
@@ -66,5 +65,4 @@ func fuzzDecode(data []byte) int {
if !bytes.Equal(decomp, blob) {
panic("content mismatch")
}
return 1
}
+4 -7
View File
@@ -14,9 +14,6 @@
// You should have received a copy of the GNU Lesser General Public License
// along with the go-ethereum library. If not, see <http://www.gnu.org/licenses/>.
//go:build gofuzz
// +build gofuzz
package bls
import (
@@ -35,7 +32,7 @@ import (
blst "github.com/supranational/blst/bindings/go"
)
func FuzzCrossPairing(data []byte) int {
func fuzzCrossPairing(data []byte) int {
input := bytes.NewReader(data)
// get random G1 points
@@ -101,7 +98,7 @@ func massageBLST(in []byte) []byte {
return out
}
func FuzzCrossG1Add(data []byte) int {
func fuzzCrossG1Add(data []byte) int {
input := bytes.NewReader(data)
// get random G1 points
@@ -139,7 +136,7 @@ func FuzzCrossG1Add(data []byte) int {
return 1
}
func FuzzCrossG2Add(data []byte) int {
func fuzzCrossG2Add(data []byte) int {
input := bytes.NewReader(data)
// get random G2 points
@@ -177,7 +174,7 @@ func FuzzCrossG2Add(data []byte) int {
return 1
}
func FuzzCrossG1MultiExp(data []byte) int {
func fuzzCrossG1MultiExp(data []byte) int {
var (
input = bytes.NewReader(data)
gethScalars []*big.Int
+97
View File
@@ -0,0 +1,97 @@
// Copyright 2023 The go-ethereum Authors
// This file is part of the go-ethereum library.
//
// The go-ethereum library is free software: you can redistribute it and/or modify
// it under the terms of the GNU Lesser General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// The go-ethereum library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public License
// along with the go-ethereum library. If not, see <http://www.gnu.org/licenses/>.
package bls
import "testing"
func FuzzCrossPairing(f *testing.F) {
f.Fuzz(func(t *testing.T, data []byte) {
fuzzCrossPairing(data)
})
}
func FuzzCrossG1Add(f *testing.F) {
f.Fuzz(func(t *testing.T, data []byte) {
fuzzCrossG1Add(data)
})
}
func FuzzCrossG2Add(f *testing.F) {
f.Fuzz(func(t *testing.T, data []byte) {
fuzzCrossG2Add(data)
})
}
func FuzzCrossG1MultiExp(f *testing.F) {
f.Fuzz(func(t *testing.T, data []byte) {
fuzzCrossG1MultiExp(data)
})
}
func FuzzG1Add(f *testing.F) {
f.Fuzz(func(t *testing.T, data []byte) {
fuzz(blsG1Add, data)
})
}
func FuzzG1Mul(f *testing.F) {
f.Fuzz(func(t *testing.T, data []byte) {
fuzz(blsG1Mul, data)
})
}
func FuzzG1MultiExp(f *testing.F) {
f.Fuzz(func(t *testing.T, data []byte) {
fuzz(blsG1MultiExp, data)
})
}
func FuzzG2Add(f *testing.F) {
f.Fuzz(func(t *testing.T, data []byte) {
fuzz(blsG2Add, data)
})
}
func FuzzG2Mul(f *testing.F) {
f.Fuzz(func(t *testing.T, data []byte) {
fuzz(blsG2Mul, data)
})
}
func FuzzG2MultiExp(f *testing.F) {
f.Fuzz(func(t *testing.T, data []byte) {
fuzz(blsG2MultiExp, data)
})
}
func FuzzPairing(f *testing.F) {
f.Fuzz(func(t *testing.T, data []byte) {
fuzz(blsPairing, data)
})
}
func FuzzMapG1(f *testing.F) {
f.Fuzz(func(t *testing.T, data []byte) {
fuzz(blsMapG1, data)
})
}
func FuzzMapG2(f *testing.F) {
f.Fuzz(func(t *testing.T, data []byte) {
fuzz(blsMapG2, data)
})
}
@@ -36,16 +36,6 @@ const (
blsMapG2 = byte(18)
)
func FuzzG1Add(data []byte) int { return fuzz(blsG1Add, data) }
func FuzzG1Mul(data []byte) int { return fuzz(blsG1Mul, data) }
func FuzzG1MultiExp(data []byte) int { return fuzz(blsG1MultiExp, data) }
func FuzzG2Add(data []byte) int { return fuzz(blsG2Add, data) }
func FuzzG2Mul(data []byte) int { return fuzz(blsG2Mul, data) }
func FuzzG2MultiExp(data []byte) int { return fuzz(blsG2MultiExp, data) }
func FuzzPairing(data []byte) int { return fuzz(blsPairing, data) }
func FuzzMapG1(data []byte) int { return fuzz(blsMapG1, data) }
func FuzzMapG2(data []byte) int { return fuzz(blsMapG2, data) }
func checkInput(id byte, inputLen int) bool {
switch id {
case blsG1Add:
+5 -8
View File
@@ -14,9 +14,6 @@
// You should have received a copy of the GNU Lesser General Public License
// along with the go-ethereum library. If not, see <http://www.gnu.org/licenses/>.
//go:build gofuzz
// +build gofuzz
package bn256
import (
@@ -64,8 +61,8 @@ func getG2Points(input io.Reader) (*cloudflare.G2, *google.G2, *bn254.G2Affine)
return xc, xg, xs
}
// FuzzAdd fuzzez bn256 addition between the Google and Cloudflare libraries.
func FuzzAdd(data []byte) int {
// fuzzAdd fuzzez bn256 addition between the Google and Cloudflare libraries.
func fuzzAdd(data []byte) int {
input := bytes.NewReader(data)
xc, xg, xs := getG1Points(input)
if xc == nil {
@@ -97,9 +94,9 @@ func FuzzAdd(data []byte) int {
return 1
}
// FuzzMul fuzzez bn256 scalar multiplication between the Google and Cloudflare
// fuzzMul fuzzez bn256 scalar multiplication between the Google and Cloudflare
// libraries.
func FuzzMul(data []byte) int {
func fuzzMul(data []byte) int {
input := bytes.NewReader(data)
pc, pg, ps := getG1Points(input)
if pc == nil {
@@ -139,7 +136,7 @@ func FuzzMul(data []byte) int {
return 1
}
func FuzzPair(data []byte) int {
func fuzzPair(data []byte) int {
input := bytes.NewReader(data)
pc, pg, ps := getG1Points(input)
if pc == nil {
@@ -1,4 +1,4 @@
// Copyright 2020 The go-ethereum Authors
// Copyright 2023 The go-ethereum Authors
// This file is part of the go-ethereum library.
//
// The go-ethereum library is free software: you can redistribute it and/or modify
@@ -14,25 +14,24 @@
// You should have received a copy of the GNU Lesser General Public License
// along with the go-ethereum library. If not, see <http://www.gnu.org/licenses/>.
package main
package bn256
import (
"fmt"
"os"
import "testing"
"github.com/ethereum/go-ethereum/tests/fuzzers/stacktrie"
)
func FuzzAdd(f *testing.F) {
f.Fuzz(func(t *testing.T, data []byte) {
fuzzAdd(data)
})
}
func main() {
if len(os.Args) != 2 {
fmt.Fprintf(os.Stderr, "Usage: debug <file>")
os.Exit(1)
}
crasher := os.Args[1]
data, err := os.ReadFile(crasher)
if err != nil {
fmt.Fprintf(os.Stderr, "error loading crasher %v: %v", crasher, err)
os.Exit(1)
}
stacktrie.Debug(data)
func FuzzMul(f *testing.F) {
f.Fuzz(func(t *testing.T, data []byte) {
fuzzMul(data)
})
}
func FuzzPair(f *testing.F) {
f.Fuzz(func(t *testing.T, data []byte) {
fuzzPair(data)
})
}
+1 -1
View File
@@ -75,7 +75,7 @@ func (f *fuzzer) readBool() bool {
// - 0 otherwise
//
// other values are reserved for future use.
func Fuzz(data []byte) int {
func fuzz(data []byte) int {
f := fuzzer{
input: bytes.NewReader(data),
exhausted: false,
@@ -1,4 +1,4 @@
// Copyright 2020 The go-ethereum Authors
// Copyright 2023 The go-ethereum Authors
// This file is part of the go-ethereum library.
//
// The go-ethereum library is free software: you can redistribute it and/or modify
@@ -14,25 +14,12 @@
// You should have received a copy of the GNU Lesser General Public License
// along with the go-ethereum library. If not, see <http://www.gnu.org/licenses/>.
package main
package difficulty
import (
"fmt"
"os"
import "testing"
"github.com/ethereum/go-ethereum/tests/fuzzers/snap"
)
func main() {
if len(os.Args) != 2 {
fmt.Fprintf(os.Stderr, "Usage: debug <file>\n")
os.Exit(1)
}
crasher := os.Args[1]
data, err := os.ReadFile(crasher)
if err != nil {
fmt.Fprintf(os.Stderr, "error loading crasher %v: %v", crasher, err)
os.Exit(1)
}
snap.FuzzTrieNodes(data)
func Fuzz(f *testing.F) {
f.Fuzz(func(t *testing.T, data []byte) {
fuzz(data)
})
}
@@ -1 +0,0 @@
ns©›,²Ô
+1 -1
View File
@@ -22,7 +22,7 @@ import (
"github.com/ethereum/go-ethereum/accounts/keystore"
)
func Fuzz(input []byte) int {
func fuzz(input []byte) int {
ks := keystore.NewKeyStore("/tmp/ks", keystore.LightScryptN, keystore.LightScryptP)
a, err := ks.NewAccount(string(input))
@@ -1,4 +1,4 @@
// Copyright 2020 The go-ethereum Authors
// Copyright 2023 The go-ethereum Authors
// This file is part of the go-ethereum library.
//
// The go-ethereum library is free software: you can redistribute it and/or modify
@@ -14,25 +14,12 @@
// You should have received a copy of the GNU Lesser General Public License
// along with the go-ethereum library. If not, see <http://www.gnu.org/licenses/>.
package main
package keystore
import (
"fmt"
"os"
import "testing"
"github.com/ethereum/go-ethereum/tests/fuzzers/difficulty"
)
func main() {
if len(os.Args) != 2 {
fmt.Fprintf(os.Stderr, "Usage: debug <file>")
os.Exit(1)
}
crasher := os.Args[1]
data, err := os.ReadFile(crasher)
if err != nil {
fmt.Fprintf(os.Stderr, "error loading crasher %v: %v", crasher, err)
os.Exit(1)
}
difficulty.Fuzz(data)
func Fuzz(f *testing.F) {
f.Fuzz(func(t *testing.T, data []byte) {
fuzz(data)
})
}
-40
View File
@@ -1,40 +0,0 @@
// Copyright 2020 The go-ethereum Authors
// This file is part of the go-ethereum library.
//
// The go-ethereum library is free software: you can redistribute it and/or modify
// it under the terms of the GNU Lesser General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// The go-ethereum library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public License
// along with the go-ethereum library. If not, see <http://www.gnu.org/licenses/>.
package main
import (
"fmt"
"os"
"github.com/ethereum/go-ethereum/tests/fuzzers/les"
)
func main() {
if len(os.Args) != 2 {
fmt.Fprintf(os.Stderr, "Usage: debug <file>\n")
fmt.Fprintf(os.Stderr, "Example\n")
fmt.Fprintf(os.Stderr, " $ debug ../crashers/4bbef6857c733a87ecf6fd8b9e7238f65eb9862a\n")
os.Exit(1)
}
crasher := os.Args[1]
data, err := os.ReadFile(crasher)
if err != nil {
fmt.Fprintf(os.Stderr, "error loading crasher %v: %v", crasher, err)
os.Exit(1)
}
les.Fuzz(data)
}
+1 -1
View File
@@ -279,7 +279,7 @@ func (f *fuzzer) doFuzz(msgCode uint64, packet interface{}) {
fn(f, peer, func() bool { return true })
}
func Fuzz(input []byte) int {
func fuzz(input []byte) int {
// We expect some large inputs
if len(input) < 100 {
return -1
+25
View File
@@ -0,0 +1,25 @@
// Copyright 2023 The go-ethereum Authors
// This file is part of the go-ethereum library.
//
// The go-ethereum library is free software: you can redistribute it and/or modify
// it under the terms of the GNU Lesser General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// The go-ethereum library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public License
// along with the go-ethereum library. If not, see <http://www.gnu.org/licenses/>.
package les
import "testing"
func Fuzz(f *testing.F) {
f.Fuzz(func(t *testing.T, data []byte) {
fuzz(data)
})
}
-40
View File
@@ -1,40 +0,0 @@
// Copyright 2020 The go-ethereum Authors
// This file is part of the go-ethereum library.
//
// The go-ethereum library is free software: you can redistribute it and/or modify
// it under the terms of the GNU Lesser General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// The go-ethereum library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public License
// along with the go-ethereum library. If not, see <http://www.gnu.org/licenses/>.
package main
import (
"fmt"
"os"
"github.com/ethereum/go-ethereum/tests/fuzzers/rangeproof"
)
func main() {
if len(os.Args) != 2 {
fmt.Fprintf(os.Stderr, "Usage: debug <file>\n")
fmt.Fprintf(os.Stderr, "Example\n")
fmt.Fprintf(os.Stderr, " $ debug ../crashers/4bbef6857c733a87ecf6fd8b9e7238f65eb9862a\n")
os.Exit(1)
}
crasher := os.Args[1]
data, err := os.ReadFile(crasher)
if err != nil {
fmt.Fprintf(os.Stderr, "error loading crasher %v: %v", crasher, err)
os.Exit(1)
}
rangeproof.Fuzz(data)
}
@@ -185,7 +185,7 @@ func (f *fuzzer) fuzz() int {
// - 0 otherwise
//
// other values are reserved for future use.
func Fuzz(input []byte) int {
func fuzz(input []byte) int {
if len(input) < 100 {
return 0
}
@@ -0,0 +1,25 @@
// Copyright 2023 The go-ethereum Authors
// This file is part of the go-ethereum library.
//
// The go-ethereum library is free software: you can redistribute it and/or modify
// it under the terms of the GNU Lesser General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// The go-ethereum library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public License
// along with the go-ethereum library. If not, see <http://www.gnu.org/licenses/>.
package rangeproof
import "testing"
func Fuzz(f *testing.F) {
f.Fuzz(func(t *testing.T, data []byte) {
fuzz(data)
})
}
+1 -1
View File
@@ -38,7 +38,7 @@ func decodeEncode(input []byte, val interface{}, i int) {
}
}
func Fuzz(input []byte) int {
func fuzz(input []byte) int {
if len(input) == 0 {
return 0
}
+25
View File
@@ -0,0 +1,25 @@
// Copyright 2023 The go-ethereum Authors
// This file is part of the go-ethereum library.
//
// The go-ethereum library is free software: you can redistribute it and/or modify
// it under the terms of the GNU Lesser General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// The go-ethereum library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public License
// along with the go-ethereum library. If not, see <http://www.gnu.org/licenses/>.
package rlp
import "testing"
func Fuzz(f *testing.F) {
f.Fuzz(func(t *testing.T, data []byte) {
fuzz(data)
})
}
@@ -1,4 +1,4 @@
// Copyright 2017 The go-ethereum Authors
// Copyright 2023 The go-ethereum Authors
// This file is part of the go-ethereum library.
//
// The go-ethereum library is free software: you can redistribute it and/or modify
@@ -17,20 +17,15 @@
package runtime
import (
"testing"
"github.com/ethereum/go-ethereum/core/vm/runtime"
)
// Fuzz is the basic entry point for the go-fuzz tool
//
// This returns 1 for valid parse:able/runnable code, 0
// for invalid opcode.
func Fuzz(input []byte) int {
_, _, err := runtime.Execute(input, input, &runtime.Config{
GasLimit: 12000000,
func Fuzz(f *testing.F) {
f.Fuzz(func(t *testing.T, code, input []byte) {
runtime.Execute(code, input, &runtime.Config{
GasLimit: 12000000,
})
})
// invalid opcode
if err != nil && len(err.Error()) > 6 && err.Error()[:7] == "invalid" {
return 0
}
return 1
}
-50
View File
@@ -1,50 +0,0 @@
// Copyright 2021 The go-ethereum Authors
// This file is part of the go-ethereum library.
//
// The go-ethereum library is free software: you can redistribute it and/or modify
// it under the terms of the GNU Lesser General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// The go-ethereum library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public License
// along with the go-ethereum library. If not, see <http://www.gnu.org/licenses/>.
// build +gofuzz
package secp256k1
import (
"fmt"
"github.com/btcsuite/btcd/btcec/v2"
"github.com/ethereum/go-ethereum/crypto/secp256k1"
fuzz "github.com/google/gofuzz"
)
func Fuzz(input []byte) int {
var (
fuzzer = fuzz.NewFromGoFuzz(input)
curveA = secp256k1.S256()
curveB = btcec.S256()
dataP1 []byte
dataP2 []byte
)
// first point
fuzzer.Fuzz(&dataP1)
x1, y1 := curveB.ScalarBaseMult(dataP1)
// second point
fuzzer.Fuzz(&dataP2)
x2, y2 := curveB.ScalarBaseMult(dataP2)
resAX, resAY := curveA.Add(x1, y1, x2, y2)
resBX, resBY := curveB.Add(x1, y1, x2, y2)
if resAX.Cmp(resBX) != 0 || resAY.Cmp(resBY) != 0 {
fmt.Printf("%s %s %s %s\n", x1, y1, x2, y2)
panic(fmt.Sprintf("Addition failed: geth: %s %s btcd: %s %s", resAX, resAY, resBX, resBY))
}
return 0
}
+33 -3
View File
@@ -16,9 +16,39 @@
package secp256k1
import "testing"
import (
"fmt"
"testing"
"github.com/btcsuite/btcd/btcec/v2"
"github.com/ethereum/go-ethereum/crypto/secp256k1"
)
func TestFuzzer(t *testing.T) {
test := "00000000N0000000/R00000000000000000U0000S0000000mkhP000000000000000U"
Fuzz([]byte(test))
a, b := "00000000N0000000/R0000000000000000", "0U0000S0000000mkhP000000000000000U"
fuzz([]byte(a), []byte(b))
}
func Fuzz(f *testing.F) {
f.Fuzz(func(t *testing.T, a, b []byte) {
fuzz(a, b)
})
}
func fuzz(dataP1, dataP2 []byte) int {
var (
curveA = secp256k1.S256()
curveB = btcec.S256()
)
// first point
x1, y1 := curveB.ScalarBaseMult(dataP1)
// second points
x2, y2 := curveB.ScalarBaseMult(dataP2)
resAX, resAY := curveA.Add(x1, y1, x2, y2)
resBX, resBY := curveB.Add(x1, y1, x2, y2)
if resAX.Cmp(resBX) != 0 || resAY.Cmp(resBY) != 0 {
fmt.Printf("%s %s %s %s\n", x1, y1, x2, y2)
panic(fmt.Sprintf("Addition failed: geth: %s %s btcd: %s %s", resAX, resAY, resBX, resBY))
}
return 0
}
-17
View File
@@ -141,20 +141,3 @@ func doFuzz(input []byte, obj interface{}, code int) int {
}
return 1
}
// To run a fuzzer, do
// $ CGO_ENABLED=0 go-fuzz-build -func FuzzTrieNodes
// $ go-fuzz
func FuzzARange(input []byte) int {
return doFuzz(input, &snap.GetAccountRangePacket{}, snap.GetAccountRangeMsg)
}
func FuzzSRange(input []byte) int {
return doFuzz(input, &snap.GetStorageRangesPacket{}, snap.GetStorageRangesMsg)
}
func FuzzByteCodes(input []byte) int {
return doFuzz(input, &snap.GetByteCodesPacket{}, snap.GetByteCodesMsg)
}
func FuzzTrieNodes(input []byte) int {
return doFuzz(input, &snap.GetTrieNodesPacket{}, snap.GetTrieNodesMsg)
}
@@ -1,4 +1,4 @@
// Copyright 2020 The go-ethereum Authors
// Copyright 2023 The go-ethereum Authors
// This file is part of the go-ethereum library.
//
// The go-ethereum library is free software: you can redistribute it and/or modify
@@ -14,30 +14,34 @@
// You should have received a copy of the GNU Lesser General Public License
// along with the go-ethereum library. If not, see <http://www.gnu.org/licenses/>.
package main
package snap
import (
"fmt"
"os"
"testing"
"github.com/ethereum/go-ethereum/log"
"github.com/ethereum/go-ethereum/tests/fuzzers/vflux"
"github.com/ethereum/go-ethereum/eth/protocols/snap"
)
func main() {
log.Root().SetHandler(log.LvlFilterHandler(log.LvlTrace, log.StreamHandler(os.Stderr, log.TerminalFormat(true))))
func FuzzARange(f *testing.F) {
f.Fuzz(func(t *testing.T, data []byte) {
doFuzz(data, &snap.GetAccountRangePacket{}, snap.GetAccountRangeMsg)
})
}
if len(os.Args) != 2 {
fmt.Fprintf(os.Stderr, "Usage: debug <file>\n")
fmt.Fprintf(os.Stderr, "Example\n")
fmt.Fprintf(os.Stderr, " $ debug ../crashers/4bbef6857c733a87ecf6fd8b9e7238f65eb9862a\n")
os.Exit(1)
}
crasher := os.Args[1]
data, err := os.ReadFile(crasher)
if err != nil {
fmt.Fprintf(os.Stderr, "error loading crasher %v: %v", crasher, err)
os.Exit(1)
}
vflux.FuzzClientPool(data)
func FuzzSRange(f *testing.F) {
f.Fuzz(func(t *testing.T, data []byte) {
doFuzz(data, &snap.GetStorageRangesPacket{}, snap.GetStorageRangesMsg)
})
}
func FuzzByteCodes(f *testing.F) {
f.Fuzz(func(t *testing.T, data []byte) {
doFuzz(data, &snap.GetByteCodesPacket{}, snap.GetByteCodesMsg)
})
}
func FuzzTrieNodes(f *testing.F) {
f.Fuzz(func(t *testing.T, data []byte) {
doFuzz(data, &snap.GetTrieNodesPacket{}, snap.GetTrieNodesMsg)
})
}
+1 -1
View File
@@ -115,7 +115,7 @@ type kv struct {
// - 0 otherwise
//
// other values are reserved for future use.
func Fuzz(data []byte) int {
func fuzz(data []byte) int {
f := fuzzer{
input: bytes.NewReader(data),
exhausted: false,
+25
View File
@@ -0,0 +1,25 @@
// Copyright 2023 The go-ethereum Authors
// This file is part of the go-ethereum library.
//
// The go-ethereum library is free software: you can redistribute it and/or modify
// it under the terms of the GNU Lesser General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// The go-ethereum library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public License
// along with the go-ethereum library. If not, see <http://www.gnu.org/licenses/>.
package stacktrie
import "testing"
func Fuzz(f *testing.F) {
f.Fuzz(func(t *testing.T, data []byte) {
fuzz(data)
})
}
-1
View File
@@ -1 +0,0 @@
asdlfkjasf23oiejfasdfadkfqlkjfasdlkfjalwk4jfalsdkfjawlefkjsadlfkjasldkfjwalefkjasdlfkjM
+1 -1
View File
@@ -130,7 +130,7 @@ func Generate(input []byte) randTest {
// - 0 otherwise
//
// other values are reserved for future use.
func Fuzz(input []byte) int {
func fuzz(input []byte) int {
program := Generate(input)
if len(program) == 0 {
return 0
+25
View File
@@ -0,0 +1,25 @@
// Copyright 2023 The go-ethereum Authors
// This file is part of the go-ethereum library.
//
// The go-ethereum library is free software: you can redistribute it and/or modify
// it under the terms of the GNU Lesser General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// The go-ethereum library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public License
// along with the go-ethereum library. If not, see <http://www.gnu.org/licenses/>.
package trie
import "testing"
func Fuzz(f *testing.F) {
f.Fuzz(func(t *testing.T, data []byte) {
fuzz(data)
})
}
+1 -1
View File
@@ -48,7 +48,7 @@ func init() {
}
}
func Fuzz(input []byte) int {
func fuzz(input []byte) int {
// Don't generate insanely large test cases, not much value in them
if len(input) > 16*1024 {
return 0
+25
View File
@@ -0,0 +1,25 @@
// Copyright 2023 The go-ethereum Authors
// This file is part of the go-ethereum library.
//
// The go-ethereum library is free software: you can redistribute it and/or modify
// it under the terms of the GNU Lesser General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// The go-ethereum library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public License
// along with the go-ethereum library. If not, see <http://www.gnu.org/licenses/>.
package txfetcher
import "testing"
func Fuzz(f *testing.F) {
f.Fuzz(func(t *testing.T, data []byte) {
fuzz(data)
})
}
+1 -1
View File
@@ -214,7 +214,7 @@ func (f *fuzzer) atomicBalanceOp(balance vfs.AtomicBalanceOperator, id enode.ID)
}
}
func FuzzClientPool(input []byte) int {
func fuzzClientPool(input []byte) int {
if len(input) > 10000 {
return -1
}
+25
View File
@@ -0,0 +1,25 @@
// Copyright 2023 The go-ethereum Authors
// This file is part of the go-ethereum library.
//
// The go-ethereum library is free software: you can redistribute it and/or modify
// it under the terms of the GNU Lesser General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// The go-ethereum library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public License
// along with the go-ethereum library. If not, see <http://www.gnu.org/licenses/>.
package vflux
import "testing"
func FuzzClientPool(f *testing.F) {
f.Fuzz(func(t *testing.T, data []byte) {
fuzzClientPool(data)
})
}