mirror of
https://github.com/lightningnetwork/lnd.git
synced 2025-05-02 16:00:30 +02:00
Merge pull request #7262 from bottlepay/fix-failure-tlv
lnwire: limit channel update reader
This commit is contained in:
commit
e29a5a59ad
@ -184,6 +184,10 @@ certain large transactions](https://github.com/lightningnetwork/lnd/pull/7100).
|
|||||||
|
|
||||||
* [Prevent nil pointer dereference during funding manager
|
* [Prevent nil pointer dereference during funding manager
|
||||||
test](https://github.com/lightningnetwork/lnd/pull/7268)
|
test](https://github.com/lightningnetwork/lnd/pull/7268)
|
||||||
|
|
||||||
|
* Fixed a [failure message parsing bug](https://github.com/lightningnetwork/lnd/pull/7262)
|
||||||
|
that caused additional failure message data to be interpreted as being part of
|
||||||
|
a channel update.
|
||||||
|
|
||||||
## `lncli`
|
## `lncli`
|
||||||
|
|
||||||
|
@ -596,9 +596,16 @@ func (f *FailInvalidOnionKey) Error() string {
|
|||||||
// attempt to parse these messages in order to retain compatibility. If we're
|
// attempt to parse these messages in order to retain compatibility. If we're
|
||||||
// unable to pull out a fully valid version, then we'll fall back to the
|
// unable to pull out a fully valid version, then we'll fall back to the
|
||||||
// regular parsing mechanism which includes the length prefix an NO type byte.
|
// regular parsing mechanism which includes the length prefix an NO type byte.
|
||||||
func parseChannelUpdateCompatabilityMode(r *bufio.Reader,
|
func parseChannelUpdateCompatabilityMode(reader io.Reader, length uint16,
|
||||||
chanUpdate *ChannelUpdate, pver uint32) error {
|
chanUpdate *ChannelUpdate, pver uint32) error {
|
||||||
|
|
||||||
|
// Instantiate a LimitReader because there may be additional data
|
||||||
|
// present after the channel update. Without limiting the stream, the
|
||||||
|
// additional data would be interpreted as channel update tlv data.
|
||||||
|
limitReader := io.LimitReader(reader, int64(length))
|
||||||
|
|
||||||
|
r := bufio.NewReader(limitReader)
|
||||||
|
|
||||||
// We'll peek out two bytes from the buffer without advancing the
|
// We'll peek out two bytes from the buffer without advancing the
|
||||||
// buffer so we can decide how to parse the remainder of it.
|
// buffer so we can decide how to parse the remainder of it.
|
||||||
maybeTypeBytes, err := r.Peek(2)
|
maybeTypeBytes, err := r.Peek(2)
|
||||||
@ -677,7 +684,7 @@ func (f *FailTemporaryChannelFailure) Decode(r io.Reader, pver uint32) error {
|
|||||||
if length != 0 {
|
if length != 0 {
|
||||||
f.Update = &ChannelUpdate{}
|
f.Update = &ChannelUpdate{}
|
||||||
return parseChannelUpdateCompatabilityMode(
|
return parseChannelUpdateCompatabilityMode(
|
||||||
bufio.NewReader(r), f.Update, pver,
|
r, length, f.Update, pver,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -761,7 +768,7 @@ func (f *FailAmountBelowMinimum) Decode(r io.Reader, pver uint32) error {
|
|||||||
|
|
||||||
f.Update = ChannelUpdate{}
|
f.Update = ChannelUpdate{}
|
||||||
return parseChannelUpdateCompatabilityMode(
|
return parseChannelUpdateCompatabilityMode(
|
||||||
bufio.NewReader(r), &f.Update, pver,
|
r, length, &f.Update, pver,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -829,7 +836,7 @@ func (f *FailFeeInsufficient) Decode(r io.Reader, pver uint32) error {
|
|||||||
|
|
||||||
f.Update = ChannelUpdate{}
|
f.Update = ChannelUpdate{}
|
||||||
return parseChannelUpdateCompatabilityMode(
|
return parseChannelUpdateCompatabilityMode(
|
||||||
bufio.NewReader(r), &f.Update, pver,
|
r, length, &f.Update, pver,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -897,7 +904,7 @@ func (f *FailIncorrectCltvExpiry) Decode(r io.Reader, pver uint32) error {
|
|||||||
|
|
||||||
f.Update = ChannelUpdate{}
|
f.Update = ChannelUpdate{}
|
||||||
return parseChannelUpdateCompatabilityMode(
|
return parseChannelUpdateCompatabilityMode(
|
||||||
bufio.NewReader(r), &f.Update, pver,
|
r, length, &f.Update, pver,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -954,7 +961,7 @@ func (f *FailExpiryTooSoon) Decode(r io.Reader, pver uint32) error {
|
|||||||
|
|
||||||
f.Update = ChannelUpdate{}
|
f.Update = ChannelUpdate{}
|
||||||
return parseChannelUpdateCompatabilityMode(
|
return parseChannelUpdateCompatabilityMode(
|
||||||
bufio.NewReader(r), &f.Update, pver,
|
r, length, &f.Update, pver,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1018,7 +1025,7 @@ func (f *FailChannelDisabled) Decode(r io.Reader, pver uint32) error {
|
|||||||
|
|
||||||
f.Update = ChannelUpdate{}
|
f.Update = ChannelUpdate{}
|
||||||
return parseChannelUpdateCompatabilityMode(
|
return parseChannelUpdateCompatabilityMode(
|
||||||
bufio.NewReader(r), &f.Update, pver,
|
r, length, &f.Update, pver,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,9 +1,9 @@
|
|||||||
package lnwire
|
package lnwire
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"bufio"
|
|
||||||
"bytes"
|
"bytes"
|
||||||
"encoding/binary"
|
"encoding/binary"
|
||||||
|
"encoding/hex"
|
||||||
"io"
|
"io"
|
||||||
"reflect"
|
"reflect"
|
||||||
"testing"
|
"testing"
|
||||||
@ -82,6 +82,44 @@ func TestEncodeDecodeCode(t *testing.T) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// TestEncodeDecodeTlv tests the ability of onion errors to be properly encoded
|
||||||
|
// and decoded with tlv data present.
|
||||||
|
func TestEncodeDecodeTlv(t *testing.T) {
|
||||||
|
t.Parallel()
|
||||||
|
|
||||||
|
for _, testFailure := range onionFailures {
|
||||||
|
testFailure := testFailure
|
||||||
|
code := testFailure.Code().String()
|
||||||
|
|
||||||
|
t.Run(code, func(t *testing.T) {
|
||||||
|
t.Parallel()
|
||||||
|
|
||||||
|
testEncodeDecodeTlv(t, testFailure)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
var testTlv, _ = hex.DecodeString("fd023104deadbeef")
|
||||||
|
|
||||||
|
func testEncodeDecodeTlv(t *testing.T, testFailure FailureMessage) { //nolint: lll,thelper
|
||||||
|
var failureMessageBuffer bytes.Buffer
|
||||||
|
|
||||||
|
err := EncodeFailureMessage(&failureMessageBuffer, testFailure, 0)
|
||||||
|
require.NoError(t, err)
|
||||||
|
|
||||||
|
failureMessageBuffer.Write(testTlv)
|
||||||
|
|
||||||
|
failure, err := DecodeFailureMessage(&failureMessageBuffer, 0)
|
||||||
|
require.NoError(t, err)
|
||||||
|
|
||||||
|
// FailIncorrectDetails already reads tlv data. Adapt the expected data.
|
||||||
|
if incorrectDetails, ok := testFailure.(*FailIncorrectDetails); ok {
|
||||||
|
incorrectDetails.extraOpaqueData = testTlv
|
||||||
|
}
|
||||||
|
|
||||||
|
require.Equal(t, testFailure, failure)
|
||||||
|
}
|
||||||
|
|
||||||
// TestChannelUpdateCompatabilityParsing tests that we're able to properly read
|
// TestChannelUpdateCompatabilityParsing tests that we're able to properly read
|
||||||
// out channel update messages encoded in an onion error payload that was
|
// out channel update messages encoded in an onion error payload that was
|
||||||
// written in the legacy (type prefixed) format.
|
// written in the legacy (type prefixed) format.
|
||||||
@ -100,7 +138,7 @@ func TestChannelUpdateCompatabilityParsing(t *testing.T) {
|
|||||||
// encoded channel update message.
|
// encoded channel update message.
|
||||||
var newChanUpdate ChannelUpdate
|
var newChanUpdate ChannelUpdate
|
||||||
err := parseChannelUpdateCompatabilityMode(
|
err := parseChannelUpdateCompatabilityMode(
|
||||||
bufio.NewReader(&b), &newChanUpdate, 0,
|
&b, uint16(b.Len()), &newChanUpdate, 0,
|
||||||
)
|
)
|
||||||
require.NoError(t, err, "unable to parse channel update")
|
require.NoError(t, err, "unable to parse channel update")
|
||||||
|
|
||||||
@ -127,7 +165,7 @@ func TestChannelUpdateCompatabilityParsing(t *testing.T) {
|
|||||||
// message even with the extra two bytes.
|
// message even with the extra two bytes.
|
||||||
var newChanUpdate2 ChannelUpdate
|
var newChanUpdate2 ChannelUpdate
|
||||||
err = parseChannelUpdateCompatabilityMode(
|
err = parseChannelUpdateCompatabilityMode(
|
||||||
bufio.NewReader(&b), &newChanUpdate2, 0,
|
&b, uint16(b.Len()), &newChanUpdate2, 0,
|
||||||
)
|
)
|
||||||
require.NoError(t, err, "unable to parse channel update")
|
require.NoError(t, err, "unable to parse channel update")
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user