mirror of
https://github.com/lightningnetwork/lnd.git
synced 2024-11-19 18:10:34 +01:00
Merge pull request #3424 from cfromknecht/tlv-limit-decode
tlv: limit decoded record size
This commit is contained in:
commit
0a5080c144
@ -8,10 +8,20 @@ import (
|
||||
"math"
|
||||
)
|
||||
|
||||
// MaxRecordSize is the maximum size of a particular record that will be parsed
|
||||
// by a stream decoder. This value is currently chosen to the be equal to the
|
||||
// maximum message size permitted by BOLT 1, as no record should be bigger than
|
||||
// an entire message.
|
||||
const MaxRecordSize = 65535 // 65KB
|
||||
|
||||
// ErrStreamNotCanonical signals that a decoded stream does not contain records
|
||||
// sorting by monotonically-increasing type.
|
||||
var ErrStreamNotCanonical = errors.New("tlv stream is not canonical")
|
||||
|
||||
// ErrRecordTooLarge signals that a decoded record has a length that is too
|
||||
// long to parse.
|
||||
var ErrRecordTooLarge = errors.New("record is too large")
|
||||
|
||||
// ErrUnknownRequiredType is an error returned when decoding an unknown and even
|
||||
// type from a Stream.
|
||||
type ErrUnknownRequiredType Type
|
||||
@ -183,6 +193,14 @@ func (s *Stream) Decode(r io.Reader) error {
|
||||
return err
|
||||
}
|
||||
|
||||
// Place a soft limit on the size of a sane record, which
|
||||
// prevents malicious encoders from causing us to allocate an
|
||||
// unbounded amount of memory when decoding variable-sized
|
||||
// fields.
|
||||
if length > MaxRecordSize {
|
||||
return ErrRecordTooLarge
|
||||
}
|
||||
|
||||
// Search the records known to the stream for this type. We'll
|
||||
// begin the search and recordIdx and walk forward until we find
|
||||
// it or the next record's type is larger.
|
||||
|
@ -49,6 +49,8 @@ type N1 struct {
|
||||
nodeAmts nodeAmts
|
||||
cltvDelta uint16
|
||||
|
||||
alias []byte
|
||||
|
||||
stream *tlv.Stream
|
||||
}
|
||||
|
||||
@ -66,6 +68,7 @@ func NewN1() *N1 {
|
||||
tlv.MakePrimitiveRecord(2, &n.scid),
|
||||
tlv.MakeStaticRecord(3, &n.nodeAmts, 49, ENodeAmts, DNodeAmts),
|
||||
tlv.MakePrimitiveRecord(254, &n.cltvDelta),
|
||||
tlv.MakePrimitiveRecord(401, &n.alias),
|
||||
)
|
||||
|
||||
return n
|
||||
@ -396,6 +399,12 @@ var tlvDecodingFailureTests = []struct {
|
||||
bytes: []byte{0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00},
|
||||
expErr: tlv.ErrStreamNotCanonical,
|
||||
},
|
||||
{
|
||||
name: "absurd record length",
|
||||
bytes: []byte{0xfd, 0x01, 0x91, 0xfe, 0xff, 0xff, 0xff, 0xff},
|
||||
expErr: tlv.ErrRecordTooLarge,
|
||||
skipN2: true,
|
||||
},
|
||||
}
|
||||
|
||||
// TestTLVDecodingSuccess asserts that the TLV parser fails to decode invalid
|
||||
|
Loading…
Reference in New Issue
Block a user