validation: correct lifetime of precomputed tx data

This makes sure `txsdata` always outlives the Script check queue (since local
objects are destructed in reverse order of construction).

This is the root cause for a security vulnerability reported by Cory Fields in
2024 that could be exploited by crafting an invalid block to cause nodes to
read freed memory. The vulnerability was covertly fixed in commit
`492e1f09943fcb6145c21d470299305a19e17d8b`.

See security advisory for CVE-2024-52911 for more details.

Github-Pull: #35209
Rebased-From: 1ed799fb21
This commit is contained in:
Antoine Poinsot
2026-05-05 07:52:08 -04:00
parent 6574cb4086
commit 0cedd6abf2

View File

@@ -2508,11 +2508,10 @@ bool Chainstate::ConnectBlock(const CBlock& block, BlockValidationState& state,
// in multiple threads). Preallocate the vector size so a new allocation
// doesn't invalidate pointers into the vector, and keep txsdata in scope
// for as long as `control`.
std::vector<PrecomputedTransactionData> txsdata(block.vtx.size());
std::optional<CCheckQueueControl<CScriptCheck>> control;
if (auto& queue = m_chainman.GetCheckQueue(); queue.HasThreads() && fScriptChecks) control.emplace(queue);
std::vector<PrecomputedTransactionData> txsdata(block.vtx.size());
std::vector<int> prevheights;
CAmount nFees = 0;
int nInputs = 0;