Skip to content

Conversation

mzumsande
Copy link
Contributor

@mzumsande mzumsande commented Dec 5, 2023

The crash, reported in #28986, happens when calling getrawtransaction for any mempool transaction with verbosity=2, while pruning, because the rpc calls IsBlockPruned(const CBlockIndex* pblockindex), which dereferences pblockindex without a check.

For ease of backporting this PR fixes it just locally in rpc/rawtransaction.cpp by moving the check for!blockindex up so that IsBlockPruned() will not be called with a nullptr. We might also want to change IsBlockPruned() so it doesn't crash when called with a nullptr, but I didn't do that here.

Fixes #28986

The crash would happen when querying a mempool transaction with verbosity=2, while pruning.
@DrahtBot
Copy link
Contributor

DrahtBot commented Dec 5, 2023

The following sections might be updated with supplementary metadata relevant to reviewers and maintainers.

Code Coverage

For detailed information about the code coverage, see the test coverage report.

Reviews

See the guideline for information on the review process.

Type Reviewers
ACK theStack, maflcko
Concept ACK jonatack
Stale ACK pablomartin4btc

If your review is incorrectly listed, please react with 👎 to this comment and the bot will ignore it on the next update.

@maflcko
Copy link
Member

maflcko commented Dec 5, 2023

lgtm ACK 494a926

A test wouldn't hurt, I'd say.

@fanquake fanquake modified the milestones: 27.0, 26.1 Dec 5, 2023
@maflcko
Copy link
Member

maflcko commented Dec 5, 2023

I guess this was introduced in f866971

@@ -396,7 +396,7 @@ static RPCHelpMan getrawtransaction()
LOCK(cs_main);
blockindex = chainman.m_blockman.LookupBlockIndex(hash_block);
}
if (verbosity == 1) {
if (verbosity == 1 || !blockindex) {
TxToJSON(*tx, hash_block, result, chainman.ActiveChainstate());
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

unrelated: I don't understand the silent fallback to verbose=1, when verbose=2 is not available. Either this should be documented, or an error should be thrown (same below).

Though, this is unrelated.

@bitcoin bitcoin deleted a comment from nogamike76 Dec 5, 2023
@maflcko
Copy link
Member

maflcko commented Dec 5, 2023

We might also want to change IsBlockPruned() so it doesn't crash when called with a nullptr, but I didn't do that here.

I think we should avoid the use of pointers when they are assumed to not be null. In C++, references exit. However, this can be done in a follow-up.

Copy link
Member

@pablomartin4btc pablomartin4btc left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

tACK 494a926

I've managed to reproduce the issue, this PR fixes it.

@mzumsande
Copy link
Contributor Author

A test wouldn't hurt, I'd say.

Will add one soon.

@pablomartin4btc
Copy link
Member

We might also want to change IsBlockPruned() so it doesn't crash when called with a nullptr, but I didn't do that here.

I think we should avoid the use of pointers when they are assumed to not be null. In C++, references exit. However, this can be done in a follow-up.

Sorry, why not fixing the issue directly here(?):

--- a/src/node/blockstorage.cpp
+++ b/src/node/blockstorage.cpp
@@ -585,7 +585,7 @@ const CBlockIndex* BlockManager::GetLastCheckpoint(const CCheckpointData& data)
 bool BlockManager::IsBlockPruned(const CBlockIndex* pblockindex)
 {
     AssertLockHeld(::cs_main);
-    return (m_have_pruned && !(pblockindex->nStatus & BLOCK_HAVE_DATA) && pblockindex->nTx > 0);
+    return (m_have_pruned && (pblockindex != nullptr) && !(pblockindex->nStatus & BLOCK_HAVE_DATA) && pblockindex->nTx > 0);
 }

Or even return false; earlier before the assert.

@mzumsande
Copy link
Contributor Author

Sorry, why not fixing the issue directly here(?):

I initially decided against this because

  1. calling IsBlockPruned() doesn't make any sense in the first place when there is no block.
  2. There were lots of refactors in the blockstorage module over the last year and I wasn't sure how cleanly this would backport.

I think that it's not one or the other, both changes make sense. However, to avoid the question if IsBlockPruned() should return true or false for a nullptr, it would probably be better change it to use a reference as maflcko suggested.

@achow101
Copy link
Member

achow101 commented Dec 5, 2023

Perhaps a test for this case? Edit: Oh, one has already been requested.

@jonatack
Copy link
Member

jonatack commented Dec 5, 2023

Concept ACK

@mzumsande
Copy link
Contributor Author

mzumsande commented Dec 5, 2023

I added a regression test (that will segfault on master). In order to trigger this, it's not enough to enable pruning, you have to actually have pruned a block, so I did this with -fastprune in the test. Because this will probably seem a bit random to someone reading the test without this context, I added a comment linking to this PR.
[Edit] Also had to reorder the test cases because the legacy-wallet tests don't work with a pruned chain.

This fails on master without the previous commit.
@mzumsande mzumsande force-pushed the 202312_fix_getrawtx_crash branch from 4a259fd to 9075a44 Compare December 5, 2023 22:13
@theStack
Copy link
Contributor

theStack commented Dec 5, 2023

Concept ACK

@DrahtBot DrahtBot removed the CI failed label Dec 6, 2023
Copy link
Contributor

@theStack theStack left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Tested ACK 9075a44

Reproduced the crash on master with my pruned node manually via

$ ./src/bitcoin-cli getrawmempool | head -n 2
[
    "sometxid...",
$ ./src/bitcoin-cli getrawtransaction sometxid... 2
error: timeout on transient error: Could not connect to the server 127.0.0.1:8332 (error code 1 - "EOF reached")

Make sure the bitcoind server is running and that you are connecting to the correct RPC port.

-----
bitcoind crashes with "Segmentation fault (core dumped)"

and verified that the PR fixes it. Also checked that the test crashes if cherry-picked on master, and succeeds in the PR branch.

@DrahtBot DrahtBot requested a review from maflcko December 6, 2023 01:58
@fanquake fanquake merged commit dde7ac5 into bitcoin:master Dec 6, 2023
@fanquake fanquake mentioned this pull request Dec 6, 2023
fanquake pushed a commit to fanquake/bitcoin that referenced this pull request Dec 6, 2023
The crash would happen when querying a mempool transaction with verbosity=2, while pruning.

Github-Pull: bitcoin#29003
Rebased-From: 494a926
fanquake pushed a commit to fanquake/bitcoin that referenced this pull request Dec 6, 2023
This fails on master without the previous commit.

Github-Pull: bitcoin#29003
Rebased-From: 9075a44
@fanquake
Copy link
Member

fanquake commented Dec 6, 2023

Added to #29011 for backporting to 26.x.

Copy link
Member

@pablomartin4btc pablomartin4btc left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ACK 9075a44 on new reg test added

@fanquake fanquake mentioned this pull request Dec 6, 2023
@maflcko maflcko modified the milestones: 26.1, 25.2 Dec 6, 2023
fanquake pushed a commit to fanquake/bitcoin that referenced this pull request Dec 6, 2023
The crash would happen when querying a mempool transaction with verbosity=2, while pruning.

Github-Pull: bitcoin#29003
Rebased-From: 494a926
fanquake pushed a commit to fanquake/bitcoin that referenced this pull request Dec 6, 2023
This fails on master without the previous commit.

Github-Pull: bitcoin#29003
Rebased-From: 9075a44
@fanquake
Copy link
Member

fanquake commented Dec 6, 2023

Added to #28768 for backporting to 25.x.

fanquake pushed a commit to fanquake/bitcoin that referenced this pull request Dec 6, 2023
The crash would happen when querying a mempool transaction with verbosity=2, while pruning.

Github-Pull: bitcoin#29003
Rebased-From: 494a926
fanquake pushed a commit to fanquake/bitcoin that referenced this pull request Dec 6, 2023
This fails on master without the previous commit.

Github-Pull: bitcoin#29003
Rebased-From: 9075a44
@mzumsande mzumsande deleted the 202312_fix_getrawtx_crash branch December 7, 2023 16:10
fanquake pushed a commit to fanquake/bitcoin that referenced this pull request Dec 8, 2023
The crash would happen when querying a mempool transaction with verbosity=2, while pruning.

Github-Pull: bitcoin#29003
Rebased-From: 494a926
fanquake pushed a commit to fanquake/bitcoin that referenced this pull request Dec 8, 2023
This fails on master without the previous commit.

Github-Pull: bitcoin#29003
Rebased-From: 9075a44
fanquake pushed a commit to fanquake/bitcoin that referenced this pull request Dec 11, 2023
The crash would happen when querying a mempool transaction with verbosity=2, while pruning.

Github-Pull: bitcoin#29003
Rebased-From: 494a926
fanquake pushed a commit to fanquake/bitcoin that referenced this pull request Dec 11, 2023
This fails on master without the previous commit.

Github-Pull: bitcoin#29003
Rebased-From: 9075a44
fanquake added a commit that referenced this pull request Dec 12, 2023
… pointer

fa5989d refactor: rpc: Pass CBlockIndex by reference instead of pointer (MarcoFalke)
fa604eb refactor: Use reference instead of pointer in IsBlockPruned (MarcoFalke)

Pull request description:

  Follow-up to #29003 (comment)

ACKs for top commit:
  TheCharlatan:
    ACK fa5989d
  pablomartin4btc:
    tACK fa5989d
  dergoegge:
    Code review ACK fa5989d

Tree-SHA512: 7449de3e3bb435dcbf438df88df343bb70f6edc3228ee7c0078f912ffb415e951ba30f8ecad916765f8cf896f0d784fe30535c5cf997e303cf5af257ade69773
fanquake pushed a commit to fanquake/bitcoin that referenced this pull request Jan 4, 2024
The crash would happen when querying a mempool transaction with verbosity=2, while pruning.

Github-Pull: bitcoin#29003
Rebased-From: 494a926
fanquake pushed a commit to fanquake/bitcoin that referenced this pull request Jan 4, 2024
This fails on master without the previous commit.

Github-Pull: bitcoin#29003
Rebased-From: 9075a44
glozow added a commit that referenced this pull request Jan 9, 2024
7b79e54 doc: update release notes for 26.x (fanquake)
ccf00b1 wallet: Fix use-after-free in WalletBatch::EraseRecords (MarcoFalke)
40252e1 ci: Set `HOMEBREW_NO_INSTALLED_DEPENDENTS_CHECK` to avoid failures (Hennadii Stepanov)
b06b14e rpc: getwalletinfo, return wallet 'birthtime' (furszy)
1283401 test: coverage for wallet birth time interaction with -reindex (furszy)
0fa47e2 wallet: fix legacy spkm default birth time (furszy)
84f4a6c wallet: birth time update during tx scanning (furszy)
074296d refactor: rename FirstKeyTimeChanged to MaybeUpdateBirthTime (furszy)
35039ac fuzz: disable BnB when SFFO is enabled (furszy)
903b462 test: add coverage for BnB-SFFO restriction (furszy)
05d0576 wallet: create tx, log resulting coin selection info (furszy)
5493ebb wallet: skip BnB when SFFO is active (Murch)
b15e2e2 test: add regression test for the getrawtransaction segfault (Martin Zumsande)
5097bb3 rpc: fix getrawtransaction segfault (Martin Zumsande)
81e744a ci: Use Ubuntu 24.04 Noble for asan (MarcoFalke)
69e53d1 ci: Use Ubuntu 24.04 Noble for tsan,tidy,fuzz (MarcoFalke)
d2c80b6 doc: Missing additions to 26.0 release notes (fanquake)
8dc2c75 doc: add historical release notes for 26.0 (fanquake)

Pull request description:

  Backports for `26.x`. Currently:
  * #28920
  * #28992
  * #28994
  * #29003
  * #29023
  * #29080
  * #29176

ACKs for top commit:
  TheCharlatan:
    ACK 7b79e54
  glozow:
    ACK 7b79e54, matches mine

Tree-SHA512: 898aec76ed3ad35e0edd0980af5bcc21bd60003bbf69e0b4f473ed2aa38c4e3b360b930bc3747cf798195906a8f9fe66417524f5e5ef40fa68f1c1aaceebdeb0
fanquake pushed a commit to fanquake/bitcoin that referenced this pull request Jan 15, 2024
The crash would happen when querying a mempool transaction with verbosity=2, while pruning.

Github-Pull: bitcoin#29003
Rebased-From: 494a926
fanquake pushed a commit to fanquake/bitcoin that referenced this pull request Jan 15, 2024
This fails on master without the previous commit.

Github-Pull: bitcoin#29003
Rebased-From: 9075a44
fanquake added a commit that referenced this pull request Jan 16, 2024
53bbda5 doc: update release notes for 25.x (fanquake)
31e1e03 test: add regression test for the getrawtransaction segfault (Martin Zumsande)
041228d rpc: fix getrawtransaction segfault (Martin Zumsande)
b86285d gui: fix crash on selecting "Mask values" in transaction view (Sebastian Falbesoner)
c21024f doc: add historical release notes for 25.1 (fanquake)

Pull request description:

  Collecting backports for the 25.x branch. Currently:
  * bitcoin-core/gui#774
  * #29003

ACKs for top commit:
  stickies-v:
    ACK 53bbda5

Tree-SHA512: 9b1ba17cce9de70d20329372ba71225dd930718a1f7db84a7be764dcfbba01c5e466255e7b95433ab6d7559ee8aaa04cc99ee5d1512d91fcc0a8015f1aa4150a
@bitcoin bitcoin locked and limited conversation to collaborators Dec 6, 2024
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

getrawtransaction xxxxxx.... 2 causes a segfault
8 participants