diff --git a/wire/msgcfcheckpt.go b/wire/msgcfcheckpt.go index 32f9575e..fc3fd532 100644 --- a/wire/msgcfcheckpt.go +++ b/wire/msgcfcheckpt.go @@ -5,6 +5,7 @@ package wire import ( + "errors" "fmt" "io" @@ -15,8 +16,17 @@ const ( // CFCheckptInterval is the gap (in number of blocks) between each // filter header checkpoint. CFCheckptInterval = 1000 + + // maxCFHeadersLen is the max number of filter headers we will attempt + // to decode. + maxCFHeadersLen = 100000 ) +// ErrInsaneCFHeaderCount signals that we were asked to decode an +// unreasonable number of cfilter headers. +var ErrInsaneCFHeaderCount = errors.New( + "refusing to decode unreasonable number of filter headers") + // MsgCFCheckpt implements the Message interface and represents a bitcoin // cfcheckpt message. It is used to deliver committed filter header information // in response to a getcfcheckpt message (MsgGetCFCheckpt). See MsgGetCFCheckpt @@ -60,6 +70,11 @@ func (msg *MsgCFCheckpt) BtcDecode(r io.Reader, pver uint32, _ MessageEncoding) return err } + // Refuse to decode an insane number of cfheaders. + if count > maxCFHeadersLen { + return ErrInsaneCFHeaderCount + } + // Create a contiguous slice of hashes to deserialize into in order to // reduce the number of allocations. msg.FilterHeaders = make([]*chainhash.Hash, count)