From 0d7d906abf858bebeaa6b4ba6ca828d7a65e6fbc Mon Sep 17 00:00:00 2001 From: Yolan Romailler Date: Fri, 12 May 2023 21:26:26 +0200 Subject: [PATCH] Adding extra data check on DecodeBlockMsg fix: types: error out on decoding BlockMsg with extraneous data Fixes OSS-fuzz issue 48208: lotus:fuzz_block_msg Signed-off-by: Yolan Romailler --- chain/types/blockmsg.go | 8 ++++++-- chain/types/blockmsg_test.go | 40 ++++++++++++++++++++++++++++++++++++ 2 files changed, 46 insertions(+), 2 deletions(-) create mode 100644 chain/types/blockmsg_test.go diff --git a/chain/types/blockmsg.go b/chain/types/blockmsg.go index f3114499d..f8f0a08db 100644 --- a/chain/types/blockmsg.go +++ b/chain/types/blockmsg.go @@ -2,6 +2,7 @@ package types import ( "bytes" + "fmt" "github.com/ipfs/go-cid" ) @@ -14,10 +15,13 @@ type BlockMsg struct { func DecodeBlockMsg(b []byte) (*BlockMsg, error) { var bm BlockMsg - if err := bm.UnmarshalCBOR(bytes.NewReader(b)); err != nil { + data := bytes.NewReader(b) + if err := bm.UnmarshalCBOR(data); err != nil { return nil, err } - + if l := data.Len(); l != 0 { + return nil, fmt.Errorf("extraneous data in BlockMsg CBOR encoding: got %d unexpected bytes", l) + } return &bm, nil } diff --git a/chain/types/blockmsg_test.go b/chain/types/blockmsg_test.go new file mode 100644 index 000000000..20cbe324d --- /dev/null +++ b/chain/types/blockmsg_test.go @@ -0,0 +1,40 @@ +package types + +import ( + "testing" + + "github.com/stretchr/testify/assert" +) + +func TestDecodeBlockMsg(t *testing.T) { + type args struct { + b []byte + } + tests := []struct { + name string + data []byte + want *BlockMsg + wantErr bool + }{ + {"decode empty BlockMsg with extra data at the end", []byte{0x83, 0xf6, 0x80, 0x80, 0x20}, new(BlockMsg), true}, + {"decode valid empty BlockMsg", []byte{0x83, 0xf6, 0x80, 0x80}, new(BlockMsg), false}, + {"decode invalid cbor", []byte{0x83, 0xf6, 0x80}, nil, true}, + } + for _, tt := range tests { + data := tt.data + want := tt.want + wantErr := tt.wantErr + t.Run(tt.name, func(t *testing.T) { + got, err := DecodeBlockMsg(data) + if wantErr { + assert.Errorf(t, err, "DecodeBlockMsg(%v)", data) + return + } + assert.NoErrorf(t, err, "DecodeBlockMsg(%v)", data) + assert.Equalf(t, want, got, "DecodeBlockMsg(%v)", data) + serialized, err := got.Serialize() + assert.NoErrorf(t, err, "DecodeBlockMsg(%v)", data) + assert.Equalf(t, serialized, data, "DecodeBlockMsg(%v)", data) + }) + } +}