offers, xpay, hsmd, gossipd: assorted fixes (v26.06.7 security, 7/7) - #9513
Merged
Merged
Conversation
nGoline
requested review from
Lagrang3,
cdecker and
daywalker90
as code owners
September 14, 2026 18:26
nGoline
force-pushed
the
port-26.06.7-misc
branch
from
September 15, 2026 12:52
49f06a7 to
5e0c0fe
Compare
… path. We check the offer and the fetched invoice in several places without saying which requirement each check comes from, so it's hard to tell what we implement and what we merely assume. Add the quotes and let check-source-bolt keep them current. Changelog-None: comments only. (cherry picked from commit 07734f7)
invoice_amount sits outside the TLV ranges an invoice must copy from our invoice_request, so the payee sets it independently of the amount in our request. (cherry picked from commit 808ad86)
We sent invreq_amount, so the invoice must have an equal invoice_amount; we passed msat=NULL into xpay_core() and used the invoice's own figure instead. The default fee cap scales off that same figure. Carry the amount we asked for through to invoice_fetched() and check it. Changelog-Fixed: xpay: check a fetched bolt12 invoice's amount is the one we asked for. (cherry picked from commit 51c9a1f)
When libhsmd rejects a request it returns NULL; close the client then, instead of from hsmd_status_bad_request. Share the report path in report_bad_req so it cannot drift from bad_req_fmt. Changelog-Fixed: print the commitment index in "bad commit secret" instead of a stack address (cherry picked from commit 869bd4d)
libhsmd returning NULL has no black-box behaviour change, so drive hsmd.c's io loop directly: io_set_finish counts the close, and a write after close aborts. Changelog-None (cherry picked from commit 523be99)
A remote peer supplies the reply path of an onion message, and its blinded hop count is a single unbounded byte. A zero-hop path parses to an empty hop array, which json_to_blinded_path rejects with NULL; offers then called plugin_err, and as an important builtin its death takes lightningd down with it. Drop a hopless reply path in lightningd when the message is decoded, and in offers log and ignore any reply path that fails to parse rather than aborting: a value that arrived from a remote peer must never terminate the plugin. Changelog-Fixed: plugins: `offers` no longer stops the node when an onion message carries a reply path with no hops. Co-Authored-By: Claude <noreply@anthropic.com> (cherry picked from commit 5fe925d)
Regression test: inject an onion message whose blinded reply path declares num_hops=0 and check the node processes it and stays up. Co-Authored-By: Claude <noreply@anthropic.com> (cherry picked from commit 5580b1b)
Signed-off-by: Rusty Russell <rusty@rustcorp.com.au> (cherry picked from commit 511106d)
Worst case, we can get flooded with 10,000 scids, and we work through them one at a time. In practice, there are more channels in more recent blocks, so we should bias towards those. The iteration is not free, but compared to all those getutxo calls with each block, it's invisible. ``` $ ./devtools/dump-gossipstore gossip_store-2026-08-17 | grep -v ' t=0 ' | sed -n 's/.*channel_announcement(\([0-9]*\)x.*).*/\1/p' | stats --histogram 962804************************************************************************ |******************************************************** |********************************** |*************** |********** |********** |******** |******* |******** |*** |* |* |*** 515419 ``` Signed-off-by: Rusty Russell <rusty@rustcorp.com.au> (cherry picked from commit cf06f3d)
nGoline
force-pushed
the
port-26.06.7-misc
branch
from
September 15, 2026 21:38
5e0c0fe to
1e3a12d
Compare
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Last of seven PRs forward-porting the v26.06.7 security point release onto master. Independent fixes that do not group with the others.
9 commits:
xpay: quote BOLT #12 requirements in the offer payment path.xpay: test that a fetched invoice's amount matches what we asked for.xpay: honour the BOLT #12 invoice_amount check.hsmd: return io_close when the handler reports an errorhsmd: test that a NULL reply closes the client exactly onceoffers: treat an unparseable reply path as absent, not fatalpytest: onion message reply path with no hops must not stop the nodegossipd: don't bother looking up ancient blocks.lightningd: prefer latest blocks when querying historic blocks.Three
Changelog-Fixed:offersno longer stops the node when an onion message carries a reply path with no hops;xpaychecks a fetched bolt12 invoice's amount is the one we asked for; and "bad commit secret" prints the commitment index rather than a stack address.For reviewers
Adds
hsmd/test/Makefileandhsmd/test/run-bad-request-close.c, a new unit test directory for hsmd.Applies cleanly to master with no conflicts, and every commit is byte-identical to its release-line original.