Browse Source

test/fuzz: fix rpc, secret_connection and pex tests (#6190)

* test/fuzz: fix rpc, secret_connection and pex tests

- ignore empty data in rpc
- provide correct IP in pex
- spawn a goroutine for Write and do multiple Read(s)

* test/fuzz: fix init in pex test

* test/fuzz: assign NewServeMux to global var

* test/fuzz: only try to Unmarshal if blob is not empty

* run fuzz tests for PRs which modify fuzz tests themselves

* test/fuzz: move MakeSwitch into init
pull/6194/head
Anton Kaliaev 4 years ago
committed by GitHub
parent
commit
36d92cd0b6
No known key found for this signature in database GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 65 additions and 31 deletions
  1. +4
    -0
      .github/workflows/fuzz-nightly.yml
  2. +17
    -15
      test/fuzz/p2p/pex/reactor_receive.go
  3. +32
    -10
      test/fuzz/p2p/secret_connection/read_write.go
  4. +12
    -6
      test/fuzz/rpc/jsonrpc/server/handler.go

+ 4
- 0
.github/workflows/fuzz-nightly.yml View File

@ -4,6 +4,10 @@ on:
workflow_dispatch: # allow running workflow manually
schedule:
- cron: '0 3 * * *'
pull_request:
branches: [master]
paths:
- "test/fuzz/**/*.go"
jobs:
fuzz-nightly-test:


+ 17
- 15
test/fuzz/p2p/pex/reactor_receive.go View File

@ -21,29 +21,31 @@ var (
func init() {
addrB := pex.NewAddrBook("./testdata/addrbook1", false)
pexR := pex.NewReactor(addrB, &pex.ReactorConfig{SeedMode: false})
if pexR == nil {
panic("NewReactor returned nil")
}
pexR = pex.NewReactor(addrB, &pex.ReactorConfig{SeedMode: false})
pexR.SetLogger(logger)
peer := newFuzzPeer()
peer = newFuzzPeer()
pexR.AddPeer(peer)
}
func Fuzz(data []byte) int {
if len(data) == 0 {
return -1
}
// MakeSwitch uses log.TestingLogger which can't be executed in init()
cfg := config.DefaultP2PConfig()
cfg.PexReactor = true
sw := p2p.MakeSwitch(cfg, 0, "127.0.0.1", "123.123.123", func(i int, sw *p2p.Switch) *p2p.Switch {
return sw
}, logger)
pexR.SetSwitch(sw)
}
func Fuzz(data []byte) int {
if len(data) == 0 {
return -1
}
pexR.Receive(pex.PexChannel, peer, data)
if !peer.IsRunning() {
// do not increase priority for msgs which lead to peer being stopped
return 0
}
return 1
}
@ -69,15 +71,15 @@ var defaultNodeInfo = p2p.NodeInfo{
0,
),
NodeID: nodeID,
ListenAddr: "0.0.0.0:8992",
ListenAddr: "127.0.0.1:0",
Moniker: "foo1",
}
func (fp *fuzzPeer) FlushStop() {}
func (fp *fuzzPeer) ID() p2p.NodeID { return nodeID }
func (fp *fuzzPeer) RemoteIP() net.IP { return net.IPv4(0, 0, 0, 0) }
func (fp *fuzzPeer) RemoteIP() net.IP { return net.IPv4(198, 163, 190, 214) }
func (fp *fuzzPeer) RemoteAddr() net.Addr {
return &net.TCPAddr{IP: fp.RemoteIP(), Port: 98991, Zone: ""}
return &net.TCPAddr{IP: fp.RemoteIP(), Port: 26656, Zone: ""}
}
func (fp *fuzzPeer) IsOutbound() bool { return false }
func (fp *fuzzPeer) IsPersistent() bool { return false }


+ 32
- 10
test/fuzz/p2p/secret_connection/read_write.go View File

@ -17,18 +17,40 @@ func Fuzz(data []byte) int {
}
fooConn, barConn := makeSecretConnPair()
n, err := fooConn.Write(data)
if err != nil {
panic(err)
}
dataRead := make([]byte, n)
m, err := barConn.Read(dataRead)
if err != nil {
panic(err)
// Run Write in a separate goroutine because if data is greater than 1024
// bytes, each Write must be followed by Read (see io.Pipe documentation).
go func() {
// Copy data because Write modifies the slice.
dataToWrite := make([]byte, len(data))
copy(dataToWrite, data)
n, err := fooConn.Write(dataToWrite)
if err != nil {
panic(err)
}
if n < len(data) {
panic(fmt.Sprintf("wanted to write %d bytes, but %d was written", len(data), n))
}
}()
dataRead := make([]byte, len(data))
totalRead := 0
for totalRead < len(data) {
buf := make([]byte, len(data)-totalRead)
m, err := barConn.Read(buf)
if err != nil {
panic(err)
}
copy(dataRead[totalRead:], buf[:m])
totalRead += m
log.Printf("total read: %d", totalRead)
}
if !bytes.Equal(data[:n], dataRead[:m]) {
panic(fmt.Sprintf("bytes written %X != read %X", data[:n], dataRead[:m]))
if !bytes.Equal(data, dataRead) {
panic("bytes written != read")
}
return 1
}


+ 12
- 6
test/fuzz/rpc/jsonrpc/server/handler.go View File

@ -6,6 +6,7 @@ import (
"io/ioutil"
"net/http"
"net/http/httptest"
"os"
"github.com/tendermint/tendermint/libs/log"
rs "github.com/tendermint/tendermint/rpc/jsonrpc/server"
@ -18,13 +19,16 @@ var rpcFuncMap = map[string]*rs.RPCFunc{
var mux *http.ServeMux
func init() {
mux := http.NewServeMux()
buf := new(bytes.Buffer)
lgr := log.NewTMLogger(buf)
mux = http.NewServeMux()
lgr := log.NewTMLogger(log.NewSyncWriter(os.Stdout))
rs.RegisterRPCFuncs(mux, rpcFuncMap, lgr)
}
func Fuzz(data []byte) int {
if len(data) == 0 {
return -1
}
req, _ := http.NewRequest("POST", "http://localhost/", bytes.NewReader(data))
rec := httptest.NewRecorder()
mux.ServeHTTP(rec, req)
@ -36,9 +40,11 @@ func Fuzz(data []byte) int {
if err := res.Body.Close(); err != nil {
panic(err)
}
recv := new(types.RPCResponse)
if err := json.Unmarshal(blob, recv); err != nil {
panic(err)
if len(blob) > 0 {
recv := new(types.RPCResponse)
if err := json.Unmarshal(blob, recv); err != nil {
panic(err)
}
}
return 1
}

Loading…
Cancel
Save