diff --git a/src/net_processing.cpp b/src/net_processing.cpp index b177cf0a5206..3241994f04ac 100644 --- a/src/net_processing.cpp +++ b/src/net_processing.cpp @@ -3747,10 +3747,17 @@ void PeerManagerImpl::ProcessMessage(CNode& pfrom, const std::string& msg_type, } if (msg_type == NetMsgType::SENDCMPCT) { - bool sendcmpct_hb{false}; + uint8_t sendcmpct_hb{0}; uint64_t sendcmpct_version{0}; vRecv >> sendcmpct_hb >> sendcmpct_version; + // BIP152: the first integer is interpreted as a boolean and MUST have a + // value of either 1 or 0. + if (sendcmpct_hb > 1) { + Misbehaving(*peer, "invalid sendcmpct announce field"); + return; + } + // Only support compact block relay with witnesses if (sendcmpct_version != CMPCTBLOCKS_VERSION) return; diff --git a/test/functional/p2p_compactblocks.py b/test/functional/p2p_compactblocks.py index da8a0aed9ac5..df8d8c39e71c 100755 --- a/test/functional/p2p_compactblocks.py +++ b/test/functional/p2p_compactblocks.py @@ -264,6 +264,16 @@ def check_announcement_of_new_block(node, peer, predicate): test_node.send_and_ping(msg_sendcmpct(announce=False, version=2)) check_announcement_of_new_block(node, test_node, lambda p: "cmpctblock" not in p.last_message and "headers" in p.last_message) + # BIP152 mandates that the announce field of a sendcmpct message is a + # boolean and MUST have a value of either 1 or 0. Sending any other value + # should be treated as misbehavior and lead to a disconnect. + def test_invalid_sendcmpct_announce(self): + node = self.nodes[0] + bad_peer = node.add_p2p_connection(TestP2PConn()) + msg = msg_sendcmpct(announce=2, version=2) + with node.assert_debug_log(['invalid sendcmpct announce field']): + bad_peer.send_await_disconnect(msg) + # This test actually causes bitcoind to (reasonably!) disconnect us, so do this last. def test_invalid_cmpctblock_message(self): self.generate(self.nodes[0], COINBASE_MATURITY + 1) @@ -999,6 +1009,9 @@ def run_test(self): # The previous test will lead to a disconnection. Reconnect before continuing. self.segwit_node = self.nodes[0].add_p2p_connection(TestP2PConn()) + self.log.info("Testing invalid announce field in sendcmpct message...") + self.test_invalid_sendcmpct_announce() + self.log.info("Testing invalid index in cmpctblock message...") self.test_invalid_cmpctblock_message()