Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 7 additions & 1 deletion src/net_processing.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -5524,7 +5524,13 @@ void PeerManagerImpl::ProcessMessage(

if (msg_type == NetMsgType::SPORK) {
CSporkMessage spork;
vRecv >> spork;
try {
vRecv >> spork;
} catch (const std::ios_base::failure& e) {
// Attribute deserialization failures to the peer; the outer catch would otherwise silently drop.
Misbehaving(*peer, 100, strprintf("malformed spork received. peer=%d error=%s", pfrom.GetId(), e.what()));
return;
}

uint256 hash = spork.GetHash();
CInv spork_inv{MSG_SPORK, hash};
Expand Down
3 changes: 2 additions & 1 deletion src/spork.h
Original file line number Diff line number Diff line change
Expand Up @@ -109,7 +109,8 @@ class CSporkMessage

SERIALIZE_METHODS(CSporkMessage, obj)
{
READWRITE(obj.nSporkID, obj.nValue, obj.nTimeSigned, obj.vchSig);
READWRITE(obj.nSporkID, obj.nValue, obj.nTimeSigned,
LIMITED_VECTOR(obj.vchSig, CPubKey::COMPACT_SIGNATURE_SIZE));
}

/**
Expand Down
11 changes: 11 additions & 0 deletions test/functional/feature_sporks.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,9 @@
# Distributed under the MIT software license, see the accompanying
# file COPYING or http://www.opensource.org/licenses/mit-license.php.

import struct

from test_framework.messages import ser_compact_size
from test_framework.p2p import MESSAGEMAP, P2PInterface
from test_framework.test_framework import BitcoinTestFramework

Expand Down Expand Up @@ -117,6 +120,14 @@ def run_test(self):

assert "" not in self.nodes[0].spork('show').keys()

# Oversized signature length prefix must trigger disconnect, not silent drop.
MAX_SIZE = 0x02000000
bad_spork = msg_spork_raw()
bad_spork.raw = struct.pack("<iqq", 10001, 0, 0) + ser_compact_size(MAX_SIZE)
bad_peer = self.nodes[0].add_p2p_connection(SporkP2PInterface())
bad_peer.send_message(bad_spork)
bad_peer.wait_for_disconnect()
Comment on lines +123 to +129

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟡 Suggestion: Directly test the CSporkMessage allocation bound

This test verifies disconnection but does not prove that CSporkMessage rejects the declared signature size before allocation. If its field reverted to ordinary vector deserialization while the new local catch remained, the MAX_SIZE input would allocate the first 5 MiB batch, fail on missing payload bytes, and still disconnect the peer. The generic serialization tests validate LimitedVectorFormatter itself, not its application to CSporkMessage. Retain a focused unit test that deserializes a complete 66-byte signature and expects std::ios_base::failure; that fails with the unbounded field and directly protects the security invariant without depending on an exception-message sentinel.

source: ['codex-general']



if __name__ == '__main__':
SporkTest().main()
Loading