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>
2423#include < unordered_map>
2524
2625namespace llmq {
26+ namespace {
27+ template <typename T>
28+ void ReadLimitedVector (CDataStream& stream, std::vector<T>& ret, const size_t max_size)
29+ {
30+ const size_t size{ReadCompactSize (stream)};
31+ if (size > max_size) {
32+ throw std::ios_base::failure (" vector size too large" );
33+ }
34+ ret.clear ();
35+ ret.reserve (size);
36+ while (ret.size () < size) {
37+ ret.emplace_back ();
38+ stream >> ret.back ();
39+ }
40+ }
41+
42+ void ReadBatchedSigShares (CDataStream& stream, std::vector<CBatchedSigShares>& ret)
43+ {
44+ const size_t size{ReadCompactSize (stream)};
45+ if (size > MAX_MSGS_TOTAL_BATCHED_SIGS ) {
46+ throw std::ios_base::failure (" QBSIGSHARES batch count too large" );
47+ }
48+ ret.clear ();
49+ ret.reserve (size);
50+
51+ size_t total_sigs_count{0 };
52+ while (ret.size () < size) {
53+ ret.emplace_back ();
54+ stream >> ret.back ();
55+ total_sigs_count += ret.back ().sigShares .size ();
56+ if (total_sigs_count > MAX_MSGS_TOTAL_BATCHED_SIGS ) {
57+ throw std::ios_base::failure (" QBSIGSHARES sig share count too large" );
58+ }
59+ }
60+ }
61+ } // namespace
62+
2763void NetSigning::ProcessMessage (CNode& pfrom, const std::string& msg_type, CDataStream& vRecv)
2864{
2965 if (msg_type == NetMsgType::QSIGREC ) {
@@ -45,13 +81,11 @@ void NetSigning::ProcessMessage(CNode& pfrom, const std::string& msg_type, CData
4581
4682 if (m_sporkman.IsSporkActive (SPORK_21_QUORUM_ALL_CONNECTED ) && msg_type == NetMsgType::QSIGSHARE ) {
4783 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 ());
84+ try {
85+ ReadLimitedVector (vRecv, receivedSigShares, CSigSharesManager::MAX_MSGS_SIG_SHARES );
86+ } catch (const std::ios_base::failure&) {
5387 BanNode (pfrom.GetId ());
54- return ;
88+ throw ;
5589 }
5690
5791 for (const auto & sigShare : receivedSigShares) {
@@ -63,13 +97,11 @@ void NetSigning::ProcessMessage(CNode& pfrom, const std::string& msg_type, CData
6397
6498 if (msg_type == NetMsgType::QSIGSESANN ) {
6599 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 ());
100+ try {
101+ ReadLimitedVector (vRecv, msgs, CSigSharesManager::MAX_MSGS_CNT_QSIGSESANN );
102+ } catch (const std::ios_base::failure&) {
71103 BanNode (pfrom.GetId ());
72- return ;
104+ throw ;
73105 }
74106 if (!std::ranges::all_of (msgs, [this , &pfrom](const auto & ann) {
75107 return m_shares_manager->ProcessMessageSigSesAnn (pfrom, ann);
@@ -80,17 +112,11 @@ void NetSigning::ProcessMessage(CNode& pfrom, const std::string& msg_type, CData
80112 } else if (msg_type == NetMsgType::QSIGSHARESINV || msg_type == NetMsgType::QGETSIGSHARES ) {
81113 std::vector<CSigSharesInv> msgs;
82114 try {
83- vRecv >> msgs;
115+ ReadLimitedVector ( vRecv, msgs, CSigSharesManager:: MAX_MSGS_CNT_QSIGSHARES ) ;
84116 } catch (const std::ios_base::failure&) {
85117 BanNode (pfrom.GetId ());
86118 throw ;
87119 }
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- }
94120 if (!std::ranges::all_of (msgs, [this , &pfrom, &msg_type](const auto & inv) {
95121 return m_shares_manager->ProcessMessageSigShares (pfrom, inv, msg_type);
96122 })) {
@@ -99,26 +125,11 @@ void NetSigning::ProcessMessage(CNode& pfrom, const std::string& msg_type, CData
99125 }
100126 } else if (msg_type == NetMsgType::QBSIGSHARES ) {
101127 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 ());
128+ try {
129+ ReadBatchedSigShares (vRecv, msgs);
130+ } catch (const std::ios_base::failure&) {
120131 BanNode (pfrom.GetId ());
121- return ;
132+ throw ;
122133 }
123134 if (!std::ranges::all_of (msgs, [this , &pfrom](const auto & bs) {
124135 return m_shares_manager->ProcessMessageBatchedSigShares (pfrom, bs);
0 commit comments