Skip to content

Commit a203928

Browse files
committed
Merge bitcoin/bitcoin#30538: Doc: add a comment referencing past vulnerability next to where it was fixed
eb0724f doc: banman: reference past vuln due to unbounded banlist (Antoine Poinsot) ad616b6 doc: net: mention past vulnerability as rationale to limit incoming message size (Antoine Poinsot) 4489117 doc: txrequest: point to past censorship vulnerability in tx re-request handling (Antoine Poinsot) 68ac954 doc: net_proc: reference past DoS vulnerability in orphan processing (Antoine Poinsot) c02d9f6 doc: net_proc: reference past defect regarding invalid GETDATA types (Antoine Poinsot) 5e3d9f2 doc: validation: add a reference to historical header spam vulnerability (Antoine Poinsot) Pull request description: It is useful when reading code to have context about why it is written or behaves the way it does. Some instances in this PR may seem obvious but i think nonetheless offer important context to anyone willing to change (or review a change to) this code. ACKs for top commit: ryanofsky: Code review ACK eb0724f. No changes since last review other than rebase Tree-SHA512: 271902f45b8130d44153d793bc1096cd22b6ce05494e67c665a5bc45754e3fc72573d303ec8fc7db4098d473760282ddbf0c1cf316947539501dfd8d7d5b8828
2 parents b9c2810 + eb0724f commit a203928

File tree

5 files changed

+20
-0
lines changed

5 files changed

+20
-0
lines changed

src/banman.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,11 @@ class CSubNet;
5454
// transaction that fails a policy check and a future version changes the
5555
// policy check so the transaction is accepted, then that transaction could
5656
// cause the network to split between old nodes and new nodes.
57+
//
58+
// NOTE: previously a misbehaving peer would get banned instead of discouraged.
59+
// This meant a peer could unboundedly grow our in-memory map of banned ips. When
60+
// receiving an ADDR message we would also compare every address received to every
61+
// item in the map. See https://bitcoincore.org/en/2024/07/03/disclose-unbounded-banlist.
5762

5863
class BanMan
5964
{

src/net.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -761,6 +761,8 @@ int V1Transport::readHeader(std::span<const uint8_t> msg_bytes)
761761
}
762762

763763
// reject messages larger than MAX_SIZE or MAX_PROTOCOL_MESSAGE_LENGTH
764+
// NOTE: failing to perform this check previously allowed a malicious peer to make us allocate 32MiB of memory per
765+
// connection. See https://bitcoincore.org/en/2024/07/03/disclose_receive_buffer_oom.
764766
if (hdr.nMessageSize > MAX_SIZE || hdr.nMessageSize > MAX_PROTOCOL_MESSAGE_LENGTH) {
765767
LogDebug(BCLog::NET, "Header error: Size too large (%s, %u bytes), peer=%d\n", SanitizeString(hdr.GetMessageType()), hdr.nMessageSize, m_node_id);
766768
return -1;

src/net_processing.cpp

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2425,6 +2425,9 @@ void PeerManagerImpl::ProcessGetData(CNode& pfrom, Peer& peer, const std::atomic
24252425
}
24262426
// else: If the first item on the queue is an unknown type, we erase it
24272427
// and continue processing the queue on the next call.
2428+
// NOTE: previously we wouldn't do so and the peer sending us a malformed GETDATA could
2429+
// result in never making progress and this thread using 100% allocated CPU. See
2430+
// https://bitcoincore.org/en/2024/07/03/disclose-getdata-cpu.
24282431
}
24292432

24302433
peer.m_getdata_requests.erase(peer.m_getdata_requests.begin(), it);
@@ -3068,6 +3071,8 @@ void PeerManagerImpl::ProcessPackageResult(const node::PackageToValidate& packag
30683071
}
30693072
}
30703073

3074+
// NOTE: the orphan processing used to be uninterruptible and quadratic, which could allow a peer to stall the node for
3075+
// hours with specially crafted transactions. See https://bitcoincore.org/en/2024/07/03/disclose-orphan-dos.
30713076
bool PeerManagerImpl::ProcessOrphanTx(Peer& peer)
30723077
{
30733078
AssertLockHeld(g_msgproc_mutex);

src/txrequest.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -92,6 +92,10 @@
9292
* peers with a nonzero number of tracked announcements.
9393
* - CPU usage is generally logarithmic in the total number of tracked announcements, plus the number of
9494
* announcements affected by an operation (amortized O(1) per announcement).
95+
*
96+
* Context:
97+
* - In an earlier version of the transaction request logic it was possible for a peer to prevent us from seeing a
98+
* specific transaction. See https://bitcoincore.org/en/2024/07/03/disclose_already_asked_for.
9599
*/
96100
class TxRequestTracker {
97101
// Avoid littering this header file with implementation details.

src/validation.cpp

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4202,6 +4202,10 @@ arith_uint256 CalculateClaimedHeadersWork(std::span<const CBlockHeader> headers)
42024202
* enforced in this function (eg by adding a new consensus rule). See comment
42034203
* in ConnectBlock().
42044204
* Note that -reindex-chainstate skips the validation that happens here!
4205+
*
4206+
* NOTE: failing to check the header's height against the last checkpoint's opened a DoS vector between
4207+
* v0.12 and v0.15 (when no additional protection was in place) whereby an attacker could unboundedly
4208+
* grow our in-memory block index. See https://bitcoincore.org/en/2024/07/03/disclose-header-spam.
42054209
*/
42064210
static bool ContextualCheckBlockHeader(const CBlockHeader& block, BlockValidationState& state, BlockManager& blockman, const ChainstateManager& chainman, const CBlockIndex* pindexPrev) EXCLUSIVE_LOCKS_REQUIRED(::cs_main)
42074211
{

0 commit comments

Comments
 (0)