bolt1

Base Lightning protocol, per BOLT #1 (docs.ppad.tech/bolt1).
git clone git://git.ppad.tech/bolt1.git
Log | Files | Refs | README | LICENSE

commit ea1a6a7c2e5c3cfd7573ee4988aaa6bed7e71586
parent 507af14c14be9fbaa27992357aa25e40c443daee
Author: Jared Tobin <jared@jtobin.io>
Date:   Sat, 10 Oct 2026 13:02:13 +0400

lib: compare TLV lengths in Word64

A length of 2^63 or more wrapped to a negative Int, passed the bounds
check, and was accepted with an empty value; parsing then resumed
inside the claimed value. Compare in Word64 before converting.

Diffstat:
Mlib/Lightning/Protocol/BOLT1/TLV.hs | 8++++----
1 file changed, 4 insertions(+), 4 deletions(-)

diff --git a/lib/Lightning/Protocol/BOLT1/TLV.hs b/lib/Lightning/Protocol/BOLT1/TLV.hs @@ -136,8 +136,8 @@ decodeTlvStreamRaw = go Nothing [] Nothing -> pure () (len, rest2) <- maybe (Left TlvNonMinimalEncoding) Right (decodeBigSize rest1) - -- Length bounds check - when (fromIntegral len > BS.length rest2) $ + -- Length bounds check (in Word64, so huge lengths can't wrap) + when (len > fromIntegral (BS.length rest2)) $ Left TlvLengthExceedsBounds let !val = BS.take (fromIntegral len) rest2 !rest3 = BS.drop (fromIntegral len) rest2 @@ -172,8 +172,8 @@ decodeTlvStreamWith isKnown = go Nothing [] Nothing -> pure () (len, rest2) <- maybe (Left TlvNonMinimalEncoding) Right (decodeBigSize rest1) - -- Length bounds check - when (fromIntegral len > BS.length rest2) $ + -- Length bounds check (in Word64, so huge lengths can't wrap) + when (len > fromIntegral (BS.length rest2)) $ Left TlvLengthExceedsBounds let !val = BS.take (fromIntegral len) rest2 !rest3 = BS.drop (fromIntegral len) rest2