From 439071e176fecfb5653f1536a863caeb75eaef13 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] 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; }