Skip to content

Commit cecc723

Browse files
holimankaralabe
authored andcommitted
tests/fuzzers: fuzzbuzz fuzzers for keystore, rlp, trie, whisper (#19910)
* fuzzers: fuzzers for keystore, rlp, trie, whisper (cred to @guidovranken) * fuzzers: move fuzzers to testdata * testdata/fuzzers: documentation * testdata/fuzzers: corpus for rlp * tests/fuzzers: fixup
1 parent 4b40b53 commit cecc723

File tree

12 files changed

+529
-0
lines changed

12 files changed

+529
-0
lines changed

fuzzbuzz.yaml

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
# bmt keystore rlp trie whisperv6
2+
3+
base: ubuntu:16.04
4+
targets:
5+
- name: rlp
6+
language: go
7+
version: "1.13"
8+
corpus: ./fuzzers/rlp/corpus
9+
harness:
10+
function: Fuzz
11+
package: github.com/ethereum/go-ethereum/tests/fuzzers/rlp
12+
checkout: github.com/ethereum/go-ethereum/
13+
- name: keystore
14+
language: go
15+
version: "1.13"
16+
corpus: ./fuzzers/keystore/corpus
17+
harness:
18+
function: Fuzz
19+
package: github.com/ethereum/go-ethereum/tests/fuzzers/keystore
20+
checkout: github.com/ethereum/go-ethereum/
21+
- name: trie
22+
language: go
23+
version: "1.13"
24+
corpus: ./fuzzers/trie/corpus
25+
harness:
26+
function: Fuzz
27+
package: github.com/ethereum/go-ethereum/tests/fuzzers/trie
28+
checkout: github.com/ethereum/go-ethereum/
29+
- name: whisperv6
30+
language: go
31+
version: "1.13"
32+
corpus: ./fuzzers/whisperv6/corpus
33+
harness:
34+
function: Fuzz
35+
package: github.com/ethereum/go-ethereum/tests/fuzzers/whisperv6
36+
checkout: github.com/ethereum/go-ethereum/

tests/fuzzers/README.txt

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
## Fuzzers
2+
3+
To run a fuzzer locally, you need [go-fuzz](https://github.com/dvyukov/go-fuzz) installed.
4+
5+
First build a fuzzing-binary out of the selected package:
6+
7+
```
8+
(cd ./rlp && CGO_ENABLED=0 go-fuzz-build .)
9+
```
10+
That command should generate a `rlp-fuzz.zip` in the `rlp/` directory. If you are already in that directory, you can do
11+
12+
```
13+
[user@work rlp]$ go-fuzz
14+
2019/11/26 13:36:54 workers: 6, corpus: 3 (3s ago), crashers: 0, restarts: 1/0, execs: 0 (0/sec), cover: 0, uptime: 3s
15+
2019/11/26 13:36:57 workers: 6, corpus: 3 (6s ago), crashers: 0, restarts: 1/0, execs: 0 (0/sec), cover: 1054, uptime: 6s
16+
2019/11/26 13:37:00 workers: 6, corpus: 3 (9s ago), crashers: 0, restarts: 1/8358, execs: 25074 (2786/sec), cover: 1054, uptime: 9s
17+
2019/11/26 13:37:03 workers: 6, corpus: 3 (12s ago), crashers: 0, restarts: 1/8497, execs: 50986 (4249/sec), cover: 1054, uptime: 12s
18+
2019/11/26 13:37:06 workers: 6, corpus: 3 (15s ago), crashers: 0, restarts: 1/9330, execs: 74640 (4976/sec), cover: 1054, uptime: 15s
19+
2019/11/26 13:37:09 workers: 6, corpus: 3 (18s ago), crashers: 0, restarts: 1/9948, execs: 99482 (5527/sec), cover: 1054, uptime: 18s
20+
2019/11/26 13:37:12 workers: 6, corpus: 3 (21s ago), crashers: 0, restarts: 1/9428, execs: 122568 (5836/sec), cover: 1054, uptime: 21s
21+
2019/11/26 13:37:15 workers: 6, corpus: 3 (24s ago), crashers: 0, restarts: 1/9676, execs: 145152 (6048/sec), cover: 1054, uptime: 24s
22+
2019/11/26 13:37:18 workers: 6, corpus: 3 (27s ago), crashers: 0, restarts: 1/9855, execs: 167538 (6205/sec), cover: 1054, uptime: 27s
23+
2019/11/26 13:37:21 workers: 6, corpus: 3 (30s ago), crashers: 0, restarts: 1/9645, execs: 192901 (6430/sec), cover: 1054, uptime: 30s
24+
2019/11/26 13:37:24 workers: 6, corpus: 3 (33s ago), crashers: 0, restarts: 1/9967, execs: 219294 (6645/sec), cover: 1054, uptime: 33s
25+
26+
```
27+
Otherwise:
28+
```
29+
go-fuzz -bin ./rlp/rlp-fuzz.zip
30+
```
31+
32+
### Notes
33+
34+
Once a 'crasher' is found, the fuzzer tries to avoid reporting the same vector twice, so stores the fault in the `suppressions` folder. Thus, if you
35+
e.g. make changes to fix a bug, you should _remove_ all data from the `suppressions`-folder, to verify that the issue is indeed resolved.
36+
37+
Also, if you have only one and the same exit-point for multiple different types of test, the suppression can make the fuzzer hide differnent types of errors. So make
38+
sure that each type of failure is unique (for an example, see the rlp fuzzer, where a counter `i` is used to differentiate between failures:
39+
40+
```golang
41+
if !bytes.Equal(input, output) {
42+
panic(fmt.Sprintf("case %d: encode-decode is not equal, \ninput : %x\noutput: %x", i, input, output))
43+
}
44+
```
45+
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
ns��,��
Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
// Copyright 2019 The go-ethereum Authors
2+
// This file is part of the go-ethereum library.
3+
//
4+
// The go-ethereum library is free software: you can redistribute it and/or modify
5+
// it under the terms of the GNU Lesser General Public License as published by
6+
// the Free Software Foundation, either version 3 of the License, or
7+
// (at your option) any later version.
8+
//
9+
// The go-ethereum library is distributed in the hope that it will be useful,
10+
// but WITHOUT ANY WARRANTY; without even the implied warranty of
11+
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12+
// GNU Lesser General Public License for more details.
13+
//
14+
// You should have received a copy of the GNU Lesser General Public License
15+
// along with the go-ethereum library. If not, see <http://www.gnu.org/licenses/>.
16+
17+
package keystore
18+
19+
import (
20+
"os"
21+
22+
"github.com/ethereum/go-ethereum/accounts/keystore"
23+
)
24+
25+
func Fuzz(input []byte) int {
26+
ks := keystore.NewKeyStore("/tmp/ks", keystore.LightScryptN, keystore.LightScryptP)
27+
28+
a, err := ks.NewAccount(string(input))
29+
if err != nil {
30+
panic(err)
31+
}
32+
if err := ks.Unlock(a, string(input)); err != nil {
33+
panic(err)
34+
}
35+
os.Remove(a.URL.Path)
36+
return 0
37+
}
1.09 KB
Binary file not shown.

tests/fuzzers/rlp/corpus/r.bin

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
ˀ����������
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
�N�������
2+
���a����P?-'�{�ЋD�Y���f�j\�E��~읕��F?1(�ij6�@�v �L��ڑ�

tests/fuzzers/rlp/rlp_fuzzer.go

Lines changed: 127 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,127 @@
1+
// Copyright 2019 The go-ethereum Authors
2+
// This file is part of the go-ethereum library.
3+
//
4+
// The go-ethereum library is free software: you can redistribute it and/or modify
5+
// it under the terms of the GNU Lesser General Public License as published by
6+
// the Free Software Foundation, either version 3 of the License, or
7+
// (at your option) any later version.
8+
//
9+
// The go-ethereum library is distributed in the hope that it will be useful,
10+
// but WITHOUT ANY WARRANTY; without even the implied warranty of
11+
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12+
// GNU Lesser General Public License for more details.
13+
//
14+
// You should have received a copy of the GNU Lesser General Public License
15+
// along with the go-ethereum library. If not, see <http://www.gnu.org/licenses/>.
16+
17+
package rlp
18+
19+
import (
20+
"bytes"
21+
"fmt"
22+
23+
"github.com/ethereum/go-ethereum/core/types"
24+
"github.com/ethereum/go-ethereum/rlp"
25+
)
26+
27+
func decodeEncode(input []byte, val interface{}, i int) {
28+
if err := rlp.DecodeBytes(input, val); err == nil {
29+
output, err := rlp.EncodeToBytes(val)
30+
if err != nil {
31+
panic(err)
32+
}
33+
if !bytes.Equal(input, output) {
34+
panic(fmt.Sprintf("case %d: encode-decode is not equal, \ninput : %x\noutput: %x", i, input, output))
35+
}
36+
}
37+
}
38+
39+
func Fuzz(input []byte) int {
40+
var i int
41+
{
42+
if len(input) > 0 {
43+
rlp.Split(input)
44+
}
45+
}
46+
{
47+
if len(input) > 0 {
48+
if elems, _, err := rlp.SplitList(input); err == nil {
49+
rlp.CountValues(elems)
50+
}
51+
}
52+
}
53+
54+
{
55+
rlp.NewStream(bytes.NewReader(input), 0).Decode(new(interface{}))
56+
}
57+
58+
{
59+
decodeEncode(input, new(interface{}), i)
60+
i++
61+
}
62+
{
63+
var v struct {
64+
Int uint
65+
String string
66+
Bytes []byte
67+
}
68+
decodeEncode(input, &v, i)
69+
i++
70+
}
71+
72+
{
73+
type Types struct {
74+
Bool bool
75+
Raw rlp.RawValue
76+
Slice []*Types
77+
Iface []interface{}
78+
}
79+
var v Types
80+
decodeEncode(input, &v, i)
81+
i++
82+
}
83+
{
84+
type AllTypes struct {
85+
Int uint
86+
String string
87+
Bytes []byte
88+
Bool bool
89+
Raw rlp.RawValue
90+
Slice []*AllTypes
91+
Array [3]*AllTypes
92+
Iface []interface{}
93+
}
94+
var v AllTypes
95+
decodeEncode(input, &v, i)
96+
i++
97+
}
98+
{
99+
decodeEncode(input, [10]byte{}, i)
100+
i++
101+
}
102+
{
103+
var v struct {
104+
Byte [10]byte
105+
Rool [10]bool
106+
}
107+
decodeEncode(input, &v, i)
108+
i++
109+
}
110+
{
111+
var h types.Header
112+
decodeEncode(input, &h, i)
113+
i++
114+
var b types.Block
115+
decodeEncode(input, &b, i)
116+
i++
117+
var t types.Transaction
118+
decodeEncode(input, &t, i)
119+
i++
120+
var txs types.Transactions
121+
decodeEncode(input, &txs, i)
122+
i++
123+
var rs types.Receipts
124+
decodeEncode(input, &rs, i)
125+
}
126+
return 0
127+
}

tests/fuzzers/trie/corpus/data

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
asdlfkjasf23oiejfasdfadkfqlkjfasdlkfjalwk4jfalsdkfjawlefkjsadlfkjasldkfjwalefkjasdlfkjM

0 commit comments

Comments
 (0)