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
pull/28379/head
Marius van der Wijden 1 year ago committed by GitHub
parent da55b23d21
commit d10a2f6ab7
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  1. 58
      crypto/blake2b/blake2b_f_fuzz.go
  2. 58
      crypto/blake2b/blake2b_f_test.go
  3. 56
      oss-fuzz.sh
  4. 170
      tests/fuzzers/abi/abifuzzer.go
  5. 164
      tests/fuzzers/abi/abifuzzer_test.go
  6. 30
      tests/fuzzers/bitutil/compress_test.go
  7. 11
      tests/fuzzers/bls12381/bls12381_fuzz.go
  8. 97
      tests/fuzzers/bls12381/bls12381_test.go
  9. 10
      tests/fuzzers/bls12381/precompile_fuzzer.go
  10. 13
      tests/fuzzers/bn256/bn256_fuzz.go
  11. 37
      tests/fuzzers/bn256/bn256_test.go
  12. 2
      tests/fuzzers/difficulty/difficulty-fuzz.go
  13. 27
      tests/fuzzers/difficulty/difficulty_test.go
  14. 1
      tests/fuzzers/keystore/corpus/0176eaf52ed014ec5c91cf4afa070dd3fd469077-1
  15. 2
      tests/fuzzers/keystore/keystore-fuzzer.go
  16. 27
      tests/fuzzers/keystore/keystore_test.go
  17. 40
      tests/fuzzers/les/debug/main.go
  18. 2
      tests/fuzzers/les/les-fuzzer.go
  19. 25
      tests/fuzzers/les/les_test.go
  20. 40
      tests/fuzzers/rangeproof/debug/main.go
  21. 2
      tests/fuzzers/rangeproof/rangeproof-fuzzer.go
  22. 25
      tests/fuzzers/rangeproof/rangeproof_test.go
  23. 2
      tests/fuzzers/rlp/rlp_fuzzer.go
  24. 25
      tests/fuzzers/rlp/rlp_test.go
  25. 21
      tests/fuzzers/runtime/runtime_test.go
  26. 50
      tests/fuzzers/secp256k1/secp_fuzzer.go
  27. 36
      tests/fuzzers/secp256k1/secp_test.go
  28. 17
      tests/fuzzers/snap/fuzz_handler.go
  29. 46
      tests/fuzzers/snap/fuzz_test.go
  30. 2
      tests/fuzzers/stacktrie/trie_fuzzer.go
  31. 25
      tests/fuzzers/stacktrie/trie_test.go
  32. 1
      tests/fuzzers/trie/corpus/data
  33. 2
      tests/fuzzers/trie/trie-fuzzer.go
  34. 25
      tests/fuzzers/trie/trie_test.go
  35. 2
      tests/fuzzers/txfetcher/txfetcher_fuzzer.go
  36. 25
      tests/fuzzers/txfetcher/txfetcher_test.go
  37. 2
      tests/fuzzers/vflux/clientpool-fuzzer.go
  38. 25
      tests/fuzzers/vflux/clientpool_test.go

@ -1,58 +0,0 @@
//go:build gofuzz
// +build gofuzz
package blake2b
import (
"encoding/binary"
)
func Fuzz(data []byte) int {
// Make sure the data confirms to the input model
if len(data) != 211 {
return 0
}
// Parse everything and call all the implementations
var (
rounds = binary.BigEndian.Uint16(data[0:2])
h [8]uint64
m [16]uint64
t [2]uint64
f uint64
)
for i := 0; i < 8; i++ {
offset := 2 + i*8
h[i] = binary.LittleEndian.Uint64(data[offset : offset+8])
}
for i := 0; i < 16; i++ {
offset := 66 + i*8
m[i] = binary.LittleEndian.Uint64(data[offset : offset+8])
}
t[0] = binary.LittleEndian.Uint64(data[194:202])
t[1] = binary.LittleEndian.Uint64(data[202:210])
if data[210]%2 == 1 { // Avoid spinning the fuzzer to hit 0/1
f = 0xFFFFFFFFFFFFFFFF
}
// Run the blake2b compression on all instruction sets and cross reference
want := h
fGeneric(&want, &m, t[0], t[1], f, uint64(rounds))
have := h
fSSE4(&have, &m, t[0], t[1], f, uint64(rounds))
if have != want {
panic("SSE4 mismatches generic algo")
}
have = h
fAVX(&have, &m, t[0], t[1], f, uint64(rounds))
if have != want {
panic("AVX mismatches generic algo")
}
have = h
fAVX2(&have, &m, t[0], t[1], f, uint64(rounds))
if have != want {
panic("AVX2 mismatches generic algo")
}
return 1
}

@ -1,6 +1,7 @@
package blake2b package blake2b
import ( import (
"encoding/binary"
"fmt" "fmt"
"reflect" "reflect"
"testing" "testing"
@ -57,3 +58,60 @@ var testVectorsF = []testVector{
}, },
}, },
} }
func Fuzz(f *testing.F) {
f.Fuzz(func(t *testing.T, data []byte) {
fuzz(data)
})
}
func fuzz(data []byte) {
// Make sure the data confirms to the input model
if len(data) != 211 {
return
}
// Parse everything and call all the implementations
var (
rounds = binary.BigEndian.Uint16(data[0:2])
h [8]uint64
m [16]uint64
t [2]uint64
f uint64
)
for i := 0; i < 8; i++ {
offset := 2 + i*8
h[i] = binary.LittleEndian.Uint64(data[offset : offset+8])
}
for i := 0; i < 16; i++ {
offset := 66 + i*8
m[i] = binary.LittleEndian.Uint64(data[offset : offset+8])
}
t[0] = binary.LittleEndian.Uint64(data[194:202])
t[1] = binary.LittleEndian.Uint64(data[202:210])
if data[210]%2 == 1 { // Avoid spinning the fuzzer to hit 0/1
f = 0xFFFFFFFFFFFFFFFF
}
// Run the blake2b compression on all instruction sets and cross reference
want := h
fGeneric(&want, &m, t[0], t[1], f, uint64(rounds))
have := h
fSSE4(&have, &m, t[0], t[1], f, uint64(rounds))
if have != want {
panic("SSE4 mismatches generic algo")
}
have = h
fAVX(&have, &m, t[0], t[1], f, uint64(rounds))
if have != want {
panic("AVX mismatches generic algo")
}
have = h
fAVX2(&have, &m, t[0], t[1], f, uint64(rounds))
if have != want {
panic("AVX2 mismatches generic algo")
}
}

@ -1,5 +1,5 @@
#/bin/bash -eu #!/bin/bash -eu
# Copyright 2020 Google Inc. # Copyright 2022 Google LLC
# #
# Licensed under the Apache License, Version 2.0 (the "License"); # Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License. # you may not use this file except in compliance with the License.
@ -15,17 +15,6 @@
# #
################################################################################ ################################################################################
# This file is for integration with Google OSS-Fuzz.
# The following ENV variables are available when executing on OSS-fuzz:
#
# /out/ $OUT Directory to store build artifacts (fuzz targets, dictionaries, options files, seed corpus archives).
# /src/ $SRC Directory to checkout source files.
# /work/ $WORK Directory to store intermediate files.
#
# $CC, $CXX, $CCC The C and C++ compiler binaries.
# $CFLAGS, $CXXFLAGS C and C++ compiler flags.
# $LIB_FUZZING_ENGINE C++ compiler argument to link fuzz target against the prebuilt engine library (e.g. libFuzzer).
# This sets the -coverpgk for the coverage report when the corpus is executed through go test # This sets the -coverpgk for the coverage report when the corpus is executed through go test
coverpkg="github.com/ethereum/go-ethereum/..." coverpkg="github.com/ethereum/go-ethereum/..."
@ -59,25 +48,38 @@ DOG
cd - cd -
} }
function compile_fuzzer { function build_native_go_fuzzer() {
# Inputs: fuzzer=$1
# $1: The package to fuzz, within go-ethereum function=$2
# $2: The name of the fuzzing function path=$3
# $3: The name to give to the final fuzzing-binary tags="-tags gofuzz"
if [[ $SANITIZER == *coverage* ]]; then
coverbuild $path $function $fuzzer $coverpkg
else
go-118-fuzz-build $tags -o $fuzzer.a -func $function $path
$CXX $CXXFLAGS $LIB_FUZZING_ENGINE $fuzzer.a -o $OUT/$fuzzer
fi
}
function compile_fuzzer() {
path=$GOPATH/src/github.com/ethereum/go-ethereum/$1 path=$GOPATH/src/github.com/ethereum/go-ethereum/$1
func=$2 function=$2
fuzzer=$3 fuzzer=$3
echo "Building $fuzzer" echo "Building $fuzzer"
cd $path
# Install build dependencies
go install github.com/AdamKorcz/go-118-fuzz-build@latest
go get github.com/AdamKorcz/go-118-fuzz-build/testing
# Do a coverage-build or a regular build # Test if file contains a line with "func $function(" and "testing.F".
if [[ $SANITIZER = *coverage* ]]; then if [ $(grep -r "func $function(" $path | grep "testing.F" | wc -l) -eq 1 ]
coverbuild $path $func $fuzzer $coverpkg then
build_native_go_fuzzer $fuzzer $function $path
else else
(cd $path && \ echo "Could not find the function: func ${function}(f *testing.F)"
go-fuzz -func $func -o $WORK/$fuzzer.a . && \
$CXX $CXXFLAGS $LIB_FUZZING_ENGINE $WORK/$fuzzer.a -o $OUT/$fuzzer)
fi fi
## Check if there exists a seed corpus file ## Check if there exists a seed corpus file
@ -87,9 +89,11 @@ function compile_fuzzer {
cp $corpusfile $OUT/ cp $corpusfile $OUT/
echo "Found seed corpus: $corpusfile" echo "Found seed corpus: $corpusfile"
fi fi
cd -
} }
compile_fuzzer tests/fuzzers/bitutil Fuzz fuzzBitutilCompress compile_fuzzer tests/fuzzers/bitutil FuzzEncoder fuzzBitutilEncoder
compile_fuzzer tests/fuzzers/bitutil FuzzDecoder fuzzBitutilDecoder
compile_fuzzer tests/fuzzers/bn256 FuzzAdd fuzzBn256Add compile_fuzzer tests/fuzzers/bn256 FuzzAdd fuzzBn256Add
compile_fuzzer tests/fuzzers/bn256 FuzzMul fuzzBn256Mul compile_fuzzer tests/fuzzers/bn256 FuzzMul fuzzBn256Mul
compile_fuzzer tests/fuzzers/bn256 FuzzPair fuzzBn256Pair compile_fuzzer tests/fuzzers/bn256 FuzzPair fuzzBn256Pair

@ -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
}

@ -17,7 +17,13 @@
package abi package abi
import ( import (
"fmt"
"reflect"
"strings"
"testing" "testing"
"github.com/ethereum/go-ethereum/accounts/abi"
fuzz "github.com/google/gofuzz"
) )
// TestReplicate can be used to replicate crashers from the fuzzing tests. // TestReplicate can be used to replicate crashers from the fuzzing tests.
@ -25,19 +31,151 @@ import (
func TestReplicate(t *testing.T) { func TestReplicate(t *testing.T) {
testString := "\x20\x20\x20\x20\x20\x20\x20\x20\x80\x00\x00\x00\x20\x20\x20\x20\x00" testString := "\x20\x20\x20\x20\x20\x20\x20\x20\x80\x00\x00\x00\x20\x20\x20\x20\x00"
data := []byte(testString) data := []byte(testString)
runFuzzer(data) fuzzAbi(data)
} }
// TestGenerateCorpus can be used to add corpus for the fuzzer. func Fuzz(f *testing.F) {
// Just replace corpusHex with the hexEncoded output you want to add to the fuzzer. f.Fuzz(func(t *testing.T, data []byte) {
func TestGenerateCorpus(t *testing.T) { fuzzAbi(data)
/* })
corpusHex := "ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff" }
data := common.FromHex(corpusHex)
checksum := sha1.Sum(data) var (
outf := fmt.Sprintf("corpus/%x", checksum) names = []string{"_name", "name", "NAME", "name_", "__", "_name_", "n"}
if err := os.WriteFile(outf, data, 0777); err != nil { 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) 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. // This file is part of the go-ethereum library.
// //
// The go-ethereum library is free software: you can redistribute it and/or modify // The go-ethereum library is free software: you can redistribute it and/or modify
@ -18,38 +18,37 @@ package bitutil
import ( import (
"bytes" "bytes"
"testing"
"github.com/ethereum/go-ethereum/common/bitutil" "github.com/ethereum/go-ethereum/common/bitutil"
) )
// Fuzz implements a go-fuzz fuzzer method to test various encoding method func FuzzEncoder(f *testing.F) {
// invocations. f.Fuzz(func(t *testing.T, data []byte) {
func Fuzz(data []byte) int { fuzzEncode(data)
if len(data) == 0 { })
return 0 }
} func FuzzDecoder(f *testing.F) {
if data[0]%2 == 0 { f.Fuzz(func(t *testing.T, data []byte) {
return fuzzEncode(data[1:]) fuzzDecode(data)
} })
return fuzzDecode(data[1:])
} }
// fuzzEncode implements a go-fuzz fuzzer method to test the bitset encoding and // fuzzEncode implements a go-fuzz fuzzer method to test the bitset encoding and
// decoding algorithm. // decoding algorithm.
func fuzzEncode(data []byte) int { func fuzzEncode(data []byte) {
proc, _ := bitutil.DecompressBytes(bitutil.CompressBytes(data), len(data)) proc, _ := bitutil.DecompressBytes(bitutil.CompressBytes(data), len(data))
if !bytes.Equal(data, proc) { if !bytes.Equal(data, proc) {
panic("content mismatch") panic("content mismatch")
} }
return 1
} }
// fuzzDecode implements a go-fuzz fuzzer method to test the bit decoding and // fuzzDecode implements a go-fuzz fuzzer method to test the bit decoding and
// reencoding algorithm. // reencoding algorithm.
func fuzzDecode(data []byte) int { func fuzzDecode(data []byte) {
blob, err := bitutil.DecompressBytes(data, 1024) blob, err := bitutil.DecompressBytes(data, 1024)
if err != nil { if err != nil {
return 0 return
} }
// re-compress it (it's OK if the re-compressed differs from the // re-compress it (it's OK if the re-compressed differs from the
// original - the first input may not have been compressed at all) // 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) { if !bytes.Equal(decomp, blob) {
panic("content mismatch") panic("content mismatch")
} }
return 1
} }

@ -14,9 +14,6 @@
// You should have received a copy of the GNU Lesser General Public License // 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/>. // along with the go-ethereum library. If not, see <http://www.gnu.org/licenses/>.
//go:build gofuzz
// +build gofuzz
package bls package bls
import ( import (
@ -35,7 +32,7 @@ import (
blst "github.com/supranational/blst/bindings/go" blst "github.com/supranational/blst/bindings/go"
) )
func FuzzCrossPairing(data []byte) int { func fuzzCrossPairing(data []byte) int {
input := bytes.NewReader(data) input := bytes.NewReader(data)
// get random G1 points // get random G1 points
@ -101,7 +98,7 @@ func massageBLST(in []byte) []byte {
return out return out
} }
func FuzzCrossG1Add(data []byte) int { func fuzzCrossG1Add(data []byte) int {
input := bytes.NewReader(data) input := bytes.NewReader(data)
// get random G1 points // get random G1 points
@ -139,7 +136,7 @@ func FuzzCrossG1Add(data []byte) int {
return 1 return 1
} }
func FuzzCrossG2Add(data []byte) int { func fuzzCrossG2Add(data []byte) int {
input := bytes.NewReader(data) input := bytes.NewReader(data)
// get random G2 points // get random G2 points
@ -177,7 +174,7 @@ func FuzzCrossG2Add(data []byte) int {
return 1 return 1
} }
func FuzzCrossG1MultiExp(data []byte) int { func fuzzCrossG1MultiExp(data []byte) int {
var ( var (
input = bytes.NewReader(data) input = bytes.NewReader(data)
gethScalars []*big.Int gethScalars []*big.Int

@ -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) 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 { func checkInput(id byte, inputLen int) bool {
switch id { switch id {
case blsG1Add: case blsG1Add:

@ -14,9 +14,6 @@
// You should have received a copy of the GNU Lesser General Public License // 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/>. // along with the go-ethereum library. If not, see <http://www.gnu.org/licenses/>.
//go:build gofuzz
// +build gofuzz
package bn256 package bn256
import ( import (
@ -64,8 +61,8 @@ func getG2Points(input io.Reader) (*cloudflare.G2, *google.G2, *bn254.G2Affine)
return xc, xg, xs return xc, xg, xs
} }
// FuzzAdd fuzzez bn256 addition between the Google and Cloudflare libraries. // fuzzAdd fuzzez bn256 addition between the Google and Cloudflare libraries.
func FuzzAdd(data []byte) int { func fuzzAdd(data []byte) int {
input := bytes.NewReader(data) input := bytes.NewReader(data)
xc, xg, xs := getG1Points(input) xc, xg, xs := getG1Points(input)
if xc == nil { if xc == nil {
@ -97,9 +94,9 @@ func FuzzAdd(data []byte) int {
return 1 return 1
} }
// FuzzMul fuzzez bn256 scalar multiplication between the Google and Cloudflare // fuzzMul fuzzez bn256 scalar multiplication between the Google and Cloudflare
// libraries. // libraries.
func FuzzMul(data []byte) int { func fuzzMul(data []byte) int {
input := bytes.NewReader(data) input := bytes.NewReader(data)
pc, pg, ps := getG1Points(input) pc, pg, ps := getG1Points(input)
if pc == nil { if pc == nil {
@ -139,7 +136,7 @@ func FuzzMul(data []byte) int {
return 1 return 1
} }
func FuzzPair(data []byte) int { func fuzzPair(data []byte) int {
input := bytes.NewReader(data) input := bytes.NewReader(data)
pc, pg, ps := getG1Points(input) pc, pg, ps := getG1Points(input)
if pc == nil { 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. // This file is part of the go-ethereum library.
// //
// The go-ethereum library is free software: you can redistribute it and/or modify // 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 // 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/>. // along with the go-ethereum library. If not, see <http://www.gnu.org/licenses/>.
package main package bn256
import ( import "testing"
"fmt"
"os"
"github.com/ethereum/go-ethereum/tests/fuzzers/snap" func FuzzAdd(f *testing.F) {
) f.Fuzz(func(t *testing.T, data []byte) {
fuzzAdd(data)
})
}
func FuzzMul(f *testing.F) {
f.Fuzz(func(t *testing.T, data []byte) {
fuzzMul(data)
})
}
func main() { func FuzzPair(f *testing.F) {
if len(os.Args) != 2 { f.Fuzz(func(t *testing.T, data []byte) {
fmt.Fprintf(os.Stderr, "Usage: debug <file>\n") fuzzPair(data)
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)
} }

@ -75,7 +75,7 @@ func (f *fuzzer) readBool() bool {
// - 0 otherwise // - 0 otherwise
// //
// other values are reserved for future use. // other values are reserved for future use.
func Fuzz(data []byte) int { func fuzz(data []byte) int {
f := fuzzer{ f := fuzzer{
input: bytes.NewReader(data), input: bytes.NewReader(data),
exhausted: false, 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. // This file is part of the go-ethereum library.
// //
// The go-ethereum library is free software: you can redistribute it and/or modify // 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 // 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/>. // along with the go-ethereum library. If not, see <http://www.gnu.org/licenses/>.
package main package difficulty
import ( import "testing"
"fmt"
"os"
"github.com/ethereum/go-ethereum/tests/fuzzers/stacktrie" func Fuzz(f *testing.F) {
) f.Fuzz(func(t *testing.T, data []byte) {
fuzz(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)
} }

@ -22,7 +22,7 @@ import (
"github.com/ethereum/go-ethereum/accounts/keystore" "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) ks := keystore.NewKeyStore("/tmp/ks", keystore.LightScryptN, keystore.LightScryptP)
a, err := ks.NewAccount(string(input)) 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. // This file is part of the go-ethereum library.
// //
// The go-ethereum library is free software: you can redistribute it and/or modify // 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 // 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/>. // along with the go-ethereum library. If not, see <http://www.gnu.org/licenses/>.
package main package keystore
import ( import "testing"
"fmt"
"os"
"github.com/ethereum/go-ethereum/tests/fuzzers/difficulty" func Fuzz(f *testing.F) {
) f.Fuzz(func(t *testing.T, data []byte) {
fuzz(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)
}
difficulty.Fuzz(data)
} }

@ -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)
}

@ -279,7 +279,7 @@ func (f *fuzzer) doFuzz(msgCode uint64, packet interface{}) {
fn(f, peer, func() bool { return true }) fn(f, peer, func() bool { return true })
} }
func Fuzz(input []byte) int { func fuzz(input []byte) int {
// We expect some large inputs // We expect some large inputs
if len(input) < 100 { if len(input) < 100 {
return -1 return -1

@ -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)
})
}

@ -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 // - 0 otherwise
// //
// other values are reserved for future use. // other values are reserved for future use.
func Fuzz(input []byte) int { func fuzz(input []byte) int {
if len(input) < 100 { if len(input) < 100 {
return 0 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)
})
}

@ -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 { if len(input) == 0 {
return 0 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 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. // This file is part of the go-ethereum library.
// //
// The go-ethereum library is free software: you can redistribute it and/or modify // The go-ethereum library is free software: you can redistribute it and/or modify
@ -17,20 +17,15 @@
package runtime package runtime
import ( import (
"testing"
"github.com/ethereum/go-ethereum/core/vm/runtime" "github.com/ethereum/go-ethereum/core/vm/runtime"
) )
// Fuzz is the basic entry point for the go-fuzz tool func Fuzz(f *testing.F) {
// f.Fuzz(func(t *testing.T, code, input []byte) {
// This returns 1 for valid parse:able/runnable code, 0 runtime.Execute(code, input, &runtime.Config{
// for invalid opcode. GasLimit: 12000000,
func Fuzz(input []byte) int { })
_, _, err := runtime.Execute(input, input, &runtime.Config{
GasLimit: 12000000,
}) })
// invalid opcode
if err != nil && len(err.Error()) > 6 && err.Error()[:7] == "invalid" {
return 0
}
return 1
} }

@ -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
}

@ -16,9 +16,39 @@
package secp256k1 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) { func TestFuzzer(t *testing.T) {
test := "00000000N0000000/R00000000000000000U0000S0000000mkhP000000000000000U" a, b := "00000000N0000000/R0000000000000000", "0U0000S0000000mkhP000000000000000U"
Fuzz([]byte(test)) 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
} }

@ -141,20 +141,3 @@ func doFuzz(input []byte, obj interface{}, code int) int {
} }
return 1 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. // This file is part of the go-ethereum library.
// //
// The go-ethereum library is free software: you can redistribute it and/or modify // 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 // 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/>. // along with the go-ethereum library. If not, see <http://www.gnu.org/licenses/>.
package main package snap
import ( import (
"fmt" "testing"
"os"
"github.com/ethereum/go-ethereum/log" "github.com/ethereum/go-ethereum/eth/protocols/snap"
"github.com/ethereum/go-ethereum/tests/fuzzers/vflux"
) )
func main() { func FuzzARange(f *testing.F) {
log.Root().SetHandler(log.LvlFilterHandler(log.LvlTrace, log.StreamHandler(os.Stderr, log.TerminalFormat(true)))) f.Fuzz(func(t *testing.T, data []byte) {
doFuzz(data, &snap.GetAccountRangePacket{}, snap.GetAccountRangeMsg)
})
}
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)
})
}
if len(os.Args) != 2 { func FuzzTrieNodes(f *testing.F) {
fmt.Fprintf(os.Stderr, "Usage: debug <file>\n") f.Fuzz(func(t *testing.T, data []byte) {
fmt.Fprintf(os.Stderr, "Example\n") doFuzz(data, &snap.GetTrieNodesPacket{}, snap.GetTrieNodesMsg)
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)
} }

@ -115,7 +115,7 @@ type kv struct {
// - 0 otherwise // - 0 otherwise
// //
// other values are reserved for future use. // other values are reserved for future use.
func Fuzz(data []byte) int { func fuzz(data []byte) int {
f := fuzzer{ f := fuzzer{
input: bytes.NewReader(data), input: bytes.NewReader(data),
exhausted: false, exhausted: false,

@ -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 +0,0 @@
asdlfkjasf23oiejfasdfadkfqlkjfasdlkfjalwk4jfalsdkfjawlefkjsadlfkjasldkfjwalefkjasdlfkjM

@ -130,7 +130,7 @@ func Generate(input []byte) randTest {
// - 0 otherwise // - 0 otherwise
// //
// other values are reserved for future use. // other values are reserved for future use.
func Fuzz(input []byte) int { func fuzz(input []byte) int {
program := Generate(input) program := Generate(input)
if len(program) == 0 { if len(program) == 0 {
return 0 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 trie
import "testing"
func Fuzz(f *testing.F) {
f.Fuzz(func(t *testing.T, data []byte) {
fuzz(data)
})
}

@ -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 // Don't generate insanely large test cases, not much value in them
if len(input) > 16*1024 { if len(input) > 16*1024 {
return 0 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 txfetcher
import "testing"
func Fuzz(f *testing.F) {
f.Fuzz(func(t *testing.T, data []byte) {
fuzz(data)
})
}

@ -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 { if len(input) > 10000 {
return -1 return -1
} }

@ -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)
})
}
Loading…
Cancel
Save