From 3f65473f641592f07f706fdafc89c881e1652fb4 Mon Sep 17 00:00:00 2001 From: Evgeniy Stratonikov Date: Fri, 18 Mar 2022 15:15:54 +0300 Subject: [PATCH] vm: add some Fuzz tests Both `IsScriptCorrect` and `VM.Run` should never panic. Signed-off-by: Evgeniy Stratonikov --- .gitignore | 14 ++++++++++++ pkg/vm/fuzz_test.go | 54 +++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 68 insertions(+) create mode 100644 pkg/vm/fuzz_test.go diff --git a/.gitignore b/.gitignore index cdaca8c9e..2a797be7f 100644 --- a/.gitignore +++ b/.gitignore @@ -42,3 +42,17 @@ coverage.html # Compiler output examples/*/*.nef examples/*/*.json + +# Fuzzing testdata. +testdata/ +!cli/testdata +!pkg/compiler/testdata +!pkg/config/testdata +!pkg/consensus/testdata +!pkg/rpc/server/testdata +!pkg/services/notary/testdata +!pkg/services/oracle/testdata +!pkg/smartcontract/testdata +pkg/vm/testdata/fuzz +!pkg/vm/testdata +!pkg/wallet/testdata diff --git a/pkg/vm/fuzz_test.go b/pkg/vm/fuzz_test.go new file mode 100644 index 000000000..5b9fc5f9a --- /dev/null +++ b/pkg/vm/fuzz_test.go @@ -0,0 +1,54 @@ +//go:build go1.18 +// +build go1.18 + +package vm + +import ( + "testing" + + "github.com/nspcc-dev/neo-go/pkg/vm/opcode" + "github.com/stretchr/testify/require" +) + +var fuzzSeedValidScripts = [][]byte{ + makeProgram(opcode.PUSH1, opcode.PUSH10, opcode.ADD), + makeProgram(opcode.PUSH10, opcode.JMP, 3, opcode.ABORT, opcode.RET), + makeProgram(opcode.PUSHINT16, 1, 2, opcode.PUSHINT32, 3, 4, opcode.DROP), + makeProgram(opcode.PUSH2, opcode.NEWARRAY, opcode.DUP, opcode.PUSH0, opcode.PUSH1, opcode.SETITEM, opcode.VALUES), + append([]byte{byte(opcode.PUSHDATA1), 10}, randomBytes(10)...), + append([]byte{byte(opcode.PUSHDATA1), 100}, randomBytes(100)...), +} + +func FuzzIsScriptCorrect(f *testing.F) { + for _, s := range fuzzSeedValidScripts { + f.Add(s) + } + f.Fuzz(func(t *testing.T, script []byte) { + require.NotPanics(t, func() { + _ = IsScriptCorrect(script, nil) + }) + }) +} + +func FuzzVMDontPanic(f *testing.F) { + for _, s := range fuzzSeedValidScripts { + f.Add(s) + } + f.Fuzz(func(t *testing.T, script []byte) { + if IsScriptCorrect(script, nil) != nil { + return + } + + v := load(script) + + // Prevent infinite loops from being reported as fail. + v.GasLimit = 1000 + v.getPrice = func(opcode.Opcode, []byte) int64 { + return 1 + } + + require.NotPanics(t, func() { + _ = v.Run() + }) + }) +}