network: check compressed payload size in decompress

Signed-off-by: Evgeniy Stratonikov <evgeniy@nspcc.ru>
This commit is contained in:
Evgeniy Stratonikov 2022-03-24 17:15:43 +03:00
parent 13999252c6
commit 34b1b52784
3 changed files with 36 additions and 0 deletions

View file

@ -21,6 +21,9 @@ func compress(source []byte) ([]byte, error) {
// decompress decompresses bytes using lz4. // decompress decompresses bytes using lz4.
func decompress(source []byte) ([]byte, error) { func decompress(source []byte) ([]byte, error) {
if len(source) < 4 {
return nil, errors.New("invalid compressed payload")
}
length := binary.LittleEndian.Uint32(source[:4]) length := binary.LittleEndian.Uint32(source[:4])
if length > payload.MaxSize { if length > payload.MaxSize {
return nil, errors.New("invalid uncompressed payload length") return nil, errors.New("invalid uncompressed payload length")

26
pkg/network/fuzz_test.go Normal file
View file

@ -0,0 +1,26 @@
//go:build go1.18
// +build go1.18
package network
import (
"math/rand"
"testing"
"github.com/nspcc-dev/neo-go/pkg/io"
"github.com/stretchr/testify/require"
)
func FuzzMessageDecode(f *testing.F) {
for i := 0; i < 100; i++ {
seed := make([]byte, rand.Uint32()%1000)
rand.Read(seed)
f.Add(seed)
}
f.Fuzz(func(t *testing.T, value []byte) {
m := new(Message)
r := io.NewBinReaderFromBuf(value)
require.NotPanics(t, func() { _ = m.Decode(r) })
})
}

View file

@ -18,6 +18,13 @@ import (
"github.com/stretchr/testify/require" "github.com/stretchr/testify/require"
) )
func TestMessageDecodeFuzzCases(t *testing.T) {
raw := []byte("10\x0200")
m := new(Message)
r := io.NewBinReaderFromBuf(raw)
require.NotPanics(t, func() { _ = m.Decode(r) })
}
func TestEncodeDecodeVersion(t *testing.T) { func TestEncodeDecodeVersion(t *testing.T) {
// message with tiny payload, shouldn't be compressed // message with tiny payload, shouldn't be compressed
expected := NewMessage(CMDVersion, &payload.Version{ expected := NewMessage(CMDVersion, &payload.Version{