Skip to content

Commit e254ff5

Browse files
committed
Introduce a maximum size for locators.
The largest sensible size for a locator is log in the number of blocks. But, as noted by Coinr8d on BCT a maximum size message could encode a hundred thousand locators. If height were used to limit the messages that could open new attacks where peers on long low diff forks would get disconnected and end up stuck. Ideally, nodes first first learn to limit the size of locators they send before limiting what would be processed, but common implementations back off with an exponent of 2 and have an implicit limit of 2^32 blocks, so they already cannot produce locators over some size. This sets the limit to an absurdly high amount of 101 in order to maximize compatibility with existing software.
1 parent 9d86aad commit e254ff5

File tree

2 files changed

+14
-0
lines changed

2 files changed

+14
-0
lines changed

src/net.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,8 @@ static const int TIMEOUT_INTERVAL = 20 * 60;
4545
static const int FEELER_INTERVAL = 120;
4646
/** The maximum number of entries in an 'inv' protocol message */
4747
static const unsigned int MAX_INV_SZ = 50000;
48+
/** The maximum number of entries in a locator */
49+
static const unsigned int MAX_LOCATOR_SZ = 101;
4850
/** The maximum number of new addresses to accumulate before announcing. */
4951
static const unsigned int MAX_ADDR_TO_SEND = 1000;
5052
/** Maximum length of incoming protocol messages (no message over 4 MB is currently acceptable). */

src/net_processing.cpp

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2018,6 +2018,12 @@ bool static ProcessMessage(CNode* pfrom, const std::string& strCommand, CDataStr
20182018
uint256 hashStop;
20192019
vRecv >> locator >> hashStop;
20202020

2021+
if (locator.vHave.size() > MAX_LOCATOR_SZ) {
2022+
LogPrint(BCLog::NET, "getblocks locator size %lld > %d, disconnect peer=%d\n", locator.vHave.size(), MAX_LOCATOR_SZ, pfrom->GetId());
2023+
pfrom->fDisconnect = true;
2024+
return true;
2025+
}
2026+
20212027
// We might have announced the currently-being-connected tip using a
20222028
// compact block, which resulted in the peer sending a getblocks
20232029
// request, which we would otherwise respond to without the new block.
@@ -2131,6 +2137,12 @@ bool static ProcessMessage(CNode* pfrom, const std::string& strCommand, CDataStr
21312137
uint256 hashStop;
21322138
vRecv >> locator >> hashStop;
21332139

2140+
if (locator.vHave.size() > MAX_LOCATOR_SZ) {
2141+
LogPrint(BCLog::NET, "getheaders locator size %lld > %d, disconnect peer=%d\n", locator.vHave.size(), MAX_LOCATOR_SZ, pfrom->GetId());
2142+
pfrom->fDisconnect = true;
2143+
return true;
2144+
}
2145+
21342146
LOCK(cs_main);
21352147
if (IsInitialBlockDownload() && !pfrom->fWhitelisted) {
21362148
LogPrint(BCLog::NET, "Ignoring getheaders from peer=%d because node is in initial block download\n", pfrom->GetId());

0 commit comments

Comments
 (0)