Skip to content

bitcoin: don't dereference a NULL transaction from a truncated block - #9485

Open
kwsantiago wants to merge 1 commit into
ElementsProject:masterfrom
privkeyio:fix/null-tx-truncated-block
Open

bitcoin: don't dereference a NULL transaction from a truncated block#9485
kwsantiago wants to merge 1 commit into
ElementsProject:masterfrom
privkeyio:fix/null-tx-truncated-block

Conversation

@kwsantiago

Copy link
Copy Markdown

pull_bitcoin_tx_only() returns NULL once the cursor runs out, and the next line writes through it:

b->tx[i] = pull_bitcoin_tx_only(b->tx, &p, &len);
b->tx[i]->chainparams = chainparams;

So a block that ends part-way through a transaction segfaults lightningd rather than being rejected by the if (!p || len) check a few lines below, which never runs.

Reproducer, on master with no other changes: truncating the block already in run-bitcoin_block_from_hex to 162 bytes is enough.

Program received signal SIGSEGV, Segmentation fault.
0x000055555555c493 in bitcoin_block_from_hex (...) at bitcoin/block.c:213
213			b->tx[i]->chainparams = chainparams;

The block arrives from the chain backend through getrawblockbyheight, so triggering it needs a bitcoind serving a malformed or otherwise unparseable block, not anything a peer can send. It is a crash on bad input from a trusted component rather than a remotely reachable issue, which is why this is a normal pull request.

The fix returns NULL the way every other parse failure in this function does. The test walks every truncation of the existing test block, so it covers the header boundary and each transaction boundary rather than one hand-picked length.

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.
@kwsantiago
kwsantiago force-pushed the fix/null-tx-truncated-block branch from f216449 to 439071e Compare September 8, 2026 19:22
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant