From 1f722b5cbf28ac17b63b088eb71994f8f43e6b0d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kyle=20=F0=9F=90=86?= Date: Tue, 8 Sep 2026 15:20:30 -0400 Subject: [PATCH 1/2] bitcoin: don't dereference a NULL transaction from a truncated block pull_bitcoin_tx_only() returns NULL once the cursor runs out, and the next line writes through it, so a block that ends mid-transaction segfaults lightningd instead of being rejected. The block comes from the chain backend via getrawblockbyheight, so this needs a bitcoind serving a malformed or unparseable block rather than anything a peer can send. Test walks every truncation of the existing test block; it segfaults at 162 bytes without the fix. --- bitcoin/block.c | 2 ++ bitcoin/test/run-bitcoin_block_from_hex.c | 3 +++ 2 files changed, 5 insertions(+) diff --git a/bitcoin/block.c b/bitcoin/block.c index 6838f2c39344..b911f6af1cfd 100644 --- a/bitcoin/block.c +++ b/bitcoin/block.c @@ -210,6 +210,8 @@ bitcoin_block_from_hex(const tal_t *ctx, const struct chainparams *chainparams, b->txids = tal_arr(b, struct bitcoin_txid, num); for (i = 0; i < num; i++) { b->tx[i] = pull_bitcoin_tx_only(b->tx, &p, &len); + if (!b->tx[i]) + return tal_free(b); b->tx[i]->chainparams = chainparams; bitcoin_txid(b->tx[i], &b->txids[i]); } diff --git a/bitcoin/test/run-bitcoin_block_from_hex.c b/bitcoin/test/run-bitcoin_block_from_hex.c index 94b26ad5d05f..3d68f975cc7f 100644 --- a/bitcoin/test/run-bitcoin_block_from_hex.c +++ b/bitcoin/test/run-bitcoin_block_from_hex.c @@ -103,6 +103,9 @@ int main(int argc, const char *argv[]) assert(bitcoin_txid_eq(&txid, &expected_txid)); tal_free(b); + for (size_t i = 1; i < strlen(block); i++) + assert(!bitcoin_block_from_hex(NULL, chainparams, block, i)); + common_shutdown(); return 0; } From 6d8242536a79b35ab9267782964dc68da328ac8b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kyle=20=F0=9F=90=86?= Date: Wed, 16 Sep 2026 13:15:50 -0400 Subject: [PATCH 2/2] bitcoin: free the de-hexed block when parsing fails linear_tx hangs off ctx, so the failure paths free b and leave it behind. --- bitcoin/block.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/bitcoin/block.c b/bitcoin/block.c index b911f6af1cfd..076d443f8915 100644 --- a/bitcoin/block.c +++ b/bitcoin/block.c @@ -155,7 +155,7 @@ bitcoin_block_from_hex(const tal_t *ctx, const struct chainparams *chainparams, /* De-hex the array. */ len = hex_data_size(hexlen); - p = linear_tx = tal_arr(ctx, u8, len); + p = linear_tx = tal_arr(b, u8, len); if (!hex_decode(hex, hexlen, linear_tx, len)) return tal_free(b);