Skip to content

Commit d32884e

Browse files
committed
llmq: bound LLMQ signing vector intake
1 parent 2a2bc9d commit d32884e

1 file changed

Lines changed: 52 additions & 39 deletions

File tree

src/llmq/net_signing.cpp

Lines changed: 52 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,6 @@
1010
#include <llmq/signing_shares.h>
1111
#include <llmq/signing.h>
1212
#include <spork.h>
13-
#include <util/std23.h>
1413

1514
#include <logging.h>
1615
#include <streams.h>
@@ -24,6 +23,45 @@
2423
#include <unordered_map>
2524

2625
namespace llmq {
26+
namespace {
27+
template <typename T>
28+
void ReadLimitedVector(CDataStream& stream, std::vector<T>& ret, const size_t max_size)
29+
{
30+
const uint64_t size{ReadCompactSize(stream)};
31+
if (size > max_size) {
32+
throw std::ios_base::failure("vector size too large");
33+
}
34+
const size_t limited_size{static_cast<size_t>(size)};
35+
ret.clear();
36+
ret.reserve(limited_size);
37+
while (ret.size() < limited_size) {
38+
ret.emplace_back();
39+
stream >> ret.back();
40+
}
41+
}
42+
43+
void ReadBatchedSigShares(CDataStream& stream, std::vector<CBatchedSigShares>& ret)
44+
{
45+
const uint64_t size{ReadCompactSize(stream)};
46+
if (size > MAX_MSGS_TOTAL_BATCHED_SIGS) {
47+
throw std::ios_base::failure("QBSIGSHARES batch count too large");
48+
}
49+
const size_t limited_size{static_cast<size_t>(size)};
50+
ret.clear();
51+
ret.reserve(limited_size);
52+
53+
size_t total_sigs_count{0};
54+
while (ret.size() < limited_size) {
55+
ret.emplace_back();
56+
stream >> ret.back();
57+
total_sigs_count += ret.back().sigShares.size();
58+
if (total_sigs_count > MAX_MSGS_TOTAL_BATCHED_SIGS) {
59+
throw std::ios_base::failure("QBSIGSHARES sig share count too large");
60+
}
61+
}
62+
}
63+
} // namespace
64+
2765
void NetSigning::ProcessMessage(CNode& pfrom, const std::string& msg_type, CDataStream& vRecv)
2866
{
2967
if (msg_type == NetMsgType::QSIGREC) {
@@ -45,13 +83,11 @@ void NetSigning::ProcessMessage(CNode& pfrom, const std::string& msg_type, CData
4583

4684
if (m_sporkman.IsSporkActive(SPORK_21_QUORUM_ALL_CONNECTED) && msg_type == NetMsgType::QSIGSHARE) {
4785
std::vector<CSigShare> receivedSigShares;
48-
vRecv >> receivedSigShares;
49-
50-
if (receivedSigShares.size() > CSigSharesManager::MAX_MSGS_SIG_SHARES) {
51-
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());
86+
try {
87+
ReadLimitedVector(vRecv, receivedSigShares, CSigSharesManager::MAX_MSGS_SIG_SHARES);
88+
} catch (const std::ios_base::failure&) {
5389
BanNode(pfrom.GetId());
54-
return;
90+
throw;
5591
}
5692

5793
for (const auto& sigShare : receivedSigShares) {
@@ -63,13 +99,11 @@ void NetSigning::ProcessMessage(CNode& pfrom, const std::string& msg_type, CData
6399

64100
if (msg_type == NetMsgType::QSIGSESANN) {
65101
std::vector<CSigSesAnn> msgs;
66-
vRecv >> msgs;
67-
if (msgs.size() > CSigSharesManager::MAX_MSGS_CNT_QSIGSESANN) {
68-
LogPrint(BCLog::LLMQ_SIGS, /* Continued */
69-
"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());
102+
try {
103+
ReadLimitedVector(vRecv, msgs, CSigSharesManager::MAX_MSGS_CNT_QSIGSESANN);
104+
} catch (const std::ios_base::failure&) {
71105
BanNode(pfrom.GetId());
72-
return;
106+
throw;
73107
}
74108
if (!std::ranges::all_of(msgs, [this, &pfrom](const auto& ann) {
75109
return m_shares_manager->ProcessMessageSigSesAnn(pfrom, ann);
@@ -80,17 +114,11 @@ void NetSigning::ProcessMessage(CNode& pfrom, const std::string& msg_type, CData
80114
} else if (msg_type == NetMsgType::QSIGSHARESINV || msg_type == NetMsgType::QGETSIGSHARES) {
81115
std::vector<CSigSharesInv> msgs;
82116
try {
83-
vRecv >> msgs;
117+
ReadLimitedVector(vRecv, msgs, CSigSharesManager::MAX_MSGS_CNT_QSIGSHARES);
84118
} catch (const std::ios_base::failure&) {
85119
BanNode(pfrom.GetId());
86120
throw;
87121
}
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-
}
94122
if (!std::ranges::all_of(msgs, [this, &pfrom, &msg_type](const auto& inv) {
95123
return m_shares_manager->ProcessMessageSigShares(pfrom, inv, msg_type);
96124
})) {
@@ -99,26 +127,11 @@ void NetSigning::ProcessMessage(CNode& pfrom, const std::string& msg_type, CData
99127
}
100128
} else if (msg_type == NetMsgType::QBSIGSHARES) {
101129
std::vector<CBatchedSigShares> msgs;
102-
const size_t msgs_size{ReadCompactSize(vRecv)};
103-
if (msgs_size > MAX_MSGS_TOTAL_BATCHED_SIGS) {
104-
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());
106-
BanNode(pfrom.GetId());
107-
return;
108-
}
109-
msgs.reserve(msgs_size);
110-
while (msgs.size() < msgs_size) {
111-
msgs.emplace_back();
112-
vRecv >> msgs.back();
113-
}
114-
const size_t totalSigsCount = std23::ranges::fold_left(msgs, size_t{0}, [](size_t s, const auto& bs) {
115-
return s + bs.sigShares.size();
116-
});
117-
if (totalSigsCount > MAX_MSGS_TOTAL_BATCHED_SIGS) {
118-
LogPrint(BCLog::LLMQ_SIGS, "NetSigning::%s -- too many sigs in QBSIGSHARES message. cnt=%d, max=%d, node=%d\n",
119-
__func__, static_cast<int>(totalSigsCount), MAX_MSGS_TOTAL_BATCHED_SIGS, pfrom.GetId());
130+
try {
131+
ReadBatchedSigShares(vRecv, msgs);
132+
} catch (const std::ios_base::failure&) {
120133
BanNode(pfrom.GetId());
121-
return;
134+
throw;
122135
}
123136
if (!std::ranges::all_of(msgs, [this, &pfrom](const auto& bs) {
124137
return m_shares_manager->ProcessMessageBatchedSigShares(pfrom, bs);

0 commit comments

Comments
 (0)