|
| 1 | +--- |
| 2 | +title: CVE-2024-52911 - Script Interpreter Remote Crash |
| 3 | +name: blog-disclose-cve-2024-52911 |
| 4 | +id: en-blog-disclose-cve-2024-52911 |
| 5 | +lang: en |
| 6 | +type: advisory |
| 7 | +layout: post |
| 8 | + |
| 9 | +## If this is a new post, reset this counter to 1. |
| 10 | +version: 1 |
| 11 | + |
| 12 | +## Only true if release announcement or security annoucement. English posts only |
| 13 | +announcement: 1 |
| 14 | + |
| 15 | +excerpt: > |
| 16 | + A specially-crafted block can be used to remotely crash a Bitcoin Core node by exploiting a use-after-free in its script interpreter. |
| 17 | +--- |
| 18 | + |
| 19 | +After Bitcoin Core 0.14.0 and before Bitcoin Core 29.0, validating a specially-crafted block may |
| 20 | +cause the node to access previously freed memory. |
| 21 | + |
| 22 | +During validation, necessary data required for checking inputs for each transaction is |
| 23 | +pre-calculated and cached. For specially crafted invalid blocks, it was possible for this data to be |
| 24 | +destroyed while it was still being accessed by a background validation thread. An attacker capable |
| 25 | +of mining a block with sufficient proof-of-work could have exploited this to crash victim nodes. |
| 26 | +Because of the nature of use-after-free bugs, it is possible that the crash could have been used for |
| 27 | +remote code execution, though constraints on the input (block) data make this unlikely. |
| 28 | + |
| 29 | +This issue is considered **High** severity. |
| 30 | + |
| 31 | +## Details |
| 32 | + |
| 33 | +By default, script validation for new blocks is dispatched to background threads via a vector of |
| 34 | +`CScriptCheck` functors. Each CScriptCheck holds a pointer to a `PrecomputedTransactionData` object |
| 35 | +which stores some data needed by each input in the transaction. Because it stores a pointer and not |
| 36 | +the data itself, care must be taken to ensure that the `PrecomputedTransactionData` outlives the |
| 37 | +`CScriptCheck`. |
| 38 | + |
| 39 | +The script checks lifetime is enforced by an RAII class, `CCheckQueueControl`. However, the control |
| 40 | +is intantiated before the precomputed transaction data. Because local objects in C++ are |
| 41 | +[destructed in reverse order of construction](https://isocpp.org/wiki/faq/dtors#order-dtors-for-locals), |
| 42 | +this means the vector of `PrecomputedTransactionData` is destroyed *before* the |
| 43 | +`CCheckQueueControl`. |
| 44 | + |
| 45 | +This is not an issue when the block is valid, as `CCheckQueueControl::Wait()` will be called before |
| 46 | +the function returns and the `PrecomputedTransactionData` gets destroyed. However, in case of an |
| 47 | +early return (when a separate check fails) a background script thread may read the precomputed |
| 48 | +transaction data after it was destroyed. An attacker could exploit this to crash victim nodes at the |
| 49 | +expense of a valid PoW at tip. |
| 50 | + |
| 51 | +## Attribution |
| 52 | + |
| 53 | +Cory Fields (MIT DCI) discovered this vulnerability and responsibly disclosed it in a detailed |
| 54 | +report containing a proof of concept for reproduction and a proposed mitigation. |
| 55 | + |
| 56 | +## Timeline |
| 57 | + |
| 58 | +- 2024-11-02 Cory Fields privately reports the bug |
| 59 | +- 2024-11-06 Pieter Wuille pushes a covert fix to already open [PR |
| 60 | + #31112](https://github.com/bitcoin/bitcoin/pull/31112) which works around the issue by removing |
| 61 | + the early returns |
| 62 | +- 2024-12-03 PR #31112 is merged |
| 63 | +- 2025-04-12 Bitcoin Core version 29.0 is released with a fix |
| 64 | +- 2026-04-19 The last vulnerable Bitcoin Core version (28.x) goes end of life |
| 65 | +- 2026-05-05 Public disclosure. |
| 66 | + |
| 67 | +{% include references.md %} |
0 commit comments