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 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+
2765void 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