net_processing: fix BIP152 first integer interpretation
What changed, and why it matters
This change tightens how Bitcoin Core handles a compact-blocks handshake message. The old code read a small number from the network and treated any non-zero value as 'true'; the new code rejects values other than 0 or 1. This prevents a peer from sending malformed values that could, in theory, be misinterpreted by downstream logic and cause inconsistent state between nodes.
Treat as a low-to-moderate hardening fix. Backport to maintained release branches if feasible, and consider auditing other P2P messages that deserialize bool fields where the protocol requires strict 0/1 values.
Security signals we found
Protocol field validation gap closed
BIP152 specification non-compliance in deserializer
Potential state inconsistency between bool interpretation and explicit 0/1 expectation
Misbehaving() punishment added for out-of-range value
Evidence from the diff
In ProcessMessage for NetMsgType::SENDCMPCT, the first field (sendcmpct_hb, the announce/high-bandwidth flag) was previously deserialized into a bool. In the Bitcoin P2P serializer a bool accepts any non-zero byte as true, but BIP152 specifies this field MUST be 0 or 1. The patch deserializes into uint8_t, validates it is <= 1, and punishes the peer via Misbehaving() otherwise. This closes a protocol-conformance gap that could allow a malicious peer to set an undefined value.
Changed components
src/net_processing.cppSENDCMPCT message handlerBIP152 compact block negotiationInspect captured patch +8 / −1
diff --git a/src/net_processing.cpp b/src/net_processing.cpp
index c01f93c2..61b8a4ec 100644
--- a/src/net_processing.cpp
+++ b/src/net_processing.cpp
@@ -3935,10 +3935,17 @@ void PeerManagerImpl::ProcessMessage(Peer& peer, CNode& pfrom, const std::string
}
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;
Why this scored 47/100
Community notes
Notes can correct, qualify, or add evidence to the AI analysis. Every note shown here has been validated by a human moderator.
The AI analysis stands alone for now. Submit a note if you can add evidence or important context.