Skip to content

Commit bc151de

Browse files
committed
fix: bound LLMQ signing vector intake
1 parent 71c74ea commit bc151de

1 file changed

Lines changed: 35 additions & 22 deletions

File tree

src/llmq/net_signing.cpp

Lines changed: 35 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,24 @@
2424
#include <unordered_map>
2525

2626
namespace llmq {
27+
namespace {
28+
template <typename T>
29+
bool ReadLimitedVector(CDataStream& stream, std::vector<T>& ret, const size_t max_size, size_t& size)
30+
{
31+
size = ReadCompactSize(stream);
32+
if (size > max_size) {
33+
return false;
34+
}
35+
ret.clear();
36+
ret.reserve(size);
37+
while (ret.size() < size) {
38+
ret.emplace_back();
39+
stream >> ret.back();
40+
}
41+
return true;
42+
}
43+
} // namespace
44+
2745
void NetSigning::ProcessMessage(CNode& pfrom, const std::string& msg_type, CDataStream& vRecv)
2846
{
2947
if (msg_type == NetMsgType::QSIGREC) {
@@ -45,11 +63,10 @@ void NetSigning::ProcessMessage(CNode& pfrom, const std::string& msg_type, CData
4563

4664
if (m_sporkman.IsSporkActive(SPORK_21_QUORUM_ALL_CONNECTED) && msg_type == NetMsgType::QSIGSHARE) {
4765
std::vector<CSigShare> receivedSigShares;
48-
vRecv >> receivedSigShares;
49-
50-
if (receivedSigShares.size() > CSigSharesManager::MAX_MSGS_SIG_SHARES) {
66+
size_t msg_size{0};
67+
if (!ReadLimitedVector(vRecv, receivedSigShares, CSigSharesManager::MAX_MSGS_SIG_SHARES, msg_size)) {
5168
LogPrint(BCLog::LLMQ_SIGS, "NetSigning::%s -- too many sigs in QSIGSHARE message. cnt=%d, max=%d, node=%d\n",
52-
__func__, receivedSigShares.size(), CSigSharesManager::MAX_MSGS_SIG_SHARES, pfrom.GetId());
69+
__func__, static_cast<int>(msg_size), CSigSharesManager::MAX_MSGS_SIG_SHARES, pfrom.GetId());
5370
BanNode(pfrom.GetId());
5471
return;
5572
}
@@ -63,11 +80,11 @@ void NetSigning::ProcessMessage(CNode& pfrom, const std::string& msg_type, CData
6380

6481
if (msg_type == NetMsgType::QSIGSESANN) {
6582
std::vector<CSigSesAnn> msgs;
66-
vRecv >> msgs;
67-
if (msgs.size() > CSigSharesManager::MAX_MSGS_CNT_QSIGSESANN) {
83+
size_t msg_size{0};
84+
if (!ReadLimitedVector(vRecv, msgs, CSigSharesManager::MAX_MSGS_CNT_QSIGSESANN, msg_size)) {
6885
LogPrint(BCLog::LLMQ_SIGS, /* Continued */
6986
"NetSigning::%s -- too many announcements in QSIGSESANN message. cnt=%d, max=%d, node=%d\n",
70-
__func__, msgs.size(), CSigSharesManager::MAX_MSGS_CNT_QSIGSESANN, pfrom.GetId());
87+
__func__, static_cast<int>(msg_size), CSigSharesManager::MAX_MSGS_CNT_QSIGSESANN, pfrom.GetId());
7188
BanNode(pfrom.GetId());
7289
return;
7390
}
@@ -80,17 +97,18 @@ void NetSigning::ProcessMessage(CNode& pfrom, const std::string& msg_type, CData
8097
} else if (msg_type == NetMsgType::QSIGSHARESINV || msg_type == NetMsgType::QGETSIGSHARES) {
8198
std::vector<CSigSharesInv> msgs;
8299
try {
83-
vRecv >> msgs;
100+
size_t msg_size{0};
101+
if (!ReadLimitedVector(vRecv, msgs, CSigSharesManager::MAX_MSGS_CNT_QSIGSHARES, msg_size)) {
102+
LogPrint(BCLog::LLMQ_SIGS, "NetSigning::%s -- too many invs in %s message. cnt=%d, max=%d, node=%d\n",
103+
__func__, msg_type, static_cast<int>(msg_size), CSigSharesManager::MAX_MSGS_CNT_QSIGSHARES,
104+
pfrom.GetId());
105+
BanNode(pfrom.GetId());
106+
return;
107+
}
84108
} catch (const std::ios_base::failure&) {
85109
BanNode(pfrom.GetId());
86110
throw;
87111
}
88-
if (msgs.size() > CSigSharesManager::MAX_MSGS_CNT_QSIGSHARES) {
89-
LogPrint(BCLog::LLMQ_SIGS, "NetSigning::%s -- too many invs in %s message. cnt=%d, max=%d, node=%d\n",
90-
__func__, msg_type, msgs.size(), CSigSharesManager::MAX_MSGS_CNT_QSIGSHARES, pfrom.GetId());
91-
BanNode(pfrom.GetId());
92-
return;
93-
}
94112
if (!std::ranges::all_of(msgs, [this, &pfrom, &msg_type](const auto& inv) {
95113
return m_shares_manager->ProcessMessageSigShares(pfrom, inv, msg_type);
96114
})) {
@@ -99,18 +117,13 @@ void NetSigning::ProcessMessage(CNode& pfrom, const std::string& msg_type, CData
99117
}
100118
} else if (msg_type == NetMsgType::QBSIGSHARES) {
101119
std::vector<CBatchedSigShares> msgs;
102-
const size_t msgs_size{ReadCompactSize(vRecv)};
103-
if (msgs_size > MAX_MSGS_TOTAL_BATCHED_SIGS) {
120+
size_t msg_size{0};
121+
if (!ReadLimitedVector(vRecv, msgs, MAX_MSGS_TOTAL_BATCHED_SIGS, msg_size)) {
104122
LogPrint(BCLog::LLMQ_SIGS, "NetSigning::%s -- too many batches in QBSIGSHARES message. cnt=%d, max=%d, node=%d\n",
105-
__func__, static_cast<int>(msgs_size), MAX_MSGS_TOTAL_BATCHED_SIGS, pfrom.GetId());
123+
__func__, static_cast<int>(msg_size), MAX_MSGS_TOTAL_BATCHED_SIGS, pfrom.GetId());
106124
BanNode(pfrom.GetId());
107125
return;
108126
}
109-
msgs.reserve(msgs_size);
110-
while (msgs.size() < msgs_size) {
111-
msgs.emplace_back();
112-
vRecv >> msgs.back();
113-
}
114127
const size_t totalSigsCount = std23::ranges::fold_left(msgs, size_t{0}, [](size_t s, const auto& bs) {
115128
return s + bs.sigShares.size();
116129
});

0 commit comments

Comments
 (0)