Fail parsing node/channel announcements with unknown even features
authorMatt Corallo <git@bluematt.me>
Wed, 29 Aug 2018 21:52:26 +0000 (17:52 -0400)
committerMatt Corallo <git@bluematt.me>
Wed, 29 Aug 2018 22:06:06 +0000 (18:06 -0400)
This is required for BOLT 7 compliance

fuzz/fuzz_targets/channel_target.rs
fuzz/fuzz_targets/router_target.rs
src/ln/msgs.rs
src/ln/peer_handler.rs
src/ln/router.rs

index ed5fa13b09cef6055629b5824a80534a19a967ea..37a67183696b13f3b2dd229af6cd2978fcdbd504 100644 (file)
@@ -124,6 +124,7 @@ pub fn do_test(data: &[u8]) {
                                Ok(msg) => msg,
                                Err(e) => match e {
                                        msgs::DecodeError::UnknownRealmByte => return,
+                                       msgs::DecodeError::UnknownRequiredFeature => return,
                                        msgs::DecodeError::BadPublicKey => return,
                                        msgs::DecodeError::BadSignature => return,
                                        msgs::DecodeError::BadText => return,
@@ -146,6 +147,7 @@ pub fn do_test(data: &[u8]) {
                                        Ok(msg) => msg,
                                        Err(e) => match e {
                                                msgs::DecodeError::UnknownRealmByte => return,
+                                               msgs::DecodeError::UnknownRequiredFeature => return,
                                                msgs::DecodeError::BadPublicKey => return,
                                                msgs::DecodeError::BadSignature => return,
                                                msgs::DecodeError::BadText => return,
index 452369e5308dd7b5fcc3203d72792194caa7a59e..469db990ffcbd8e949fc8d722304d75dfb3f4a3b 100644 (file)
@@ -75,6 +75,7 @@ pub fn do_test(data: &[u8]) {
                                Ok(msg) => msg,
                                Err(e) => match e {
                                        msgs::DecodeError::UnknownRealmByte => return,
+                                       msgs::DecodeError::UnknownRequiredFeature => return,
                                        msgs::DecodeError::BadPublicKey => return,
                                        msgs::DecodeError::BadSignature => return,
                                        msgs::DecodeError::BadText => return,
index 42ee9d63e345e85ab3b44060c721fe645b055224..072383c11cab4a1670e0dfe322a0315d5daebe1c 100644 (file)
@@ -28,6 +28,8 @@ pub trait MsgEncodable {
 pub enum DecodeError {
        /// Unknown realm byte in an OnionHopData packet
        UnknownRealmByte,
+       /// Unknown feature mandating we fail to parse message
+       UnknownRequiredFeature,
        /// Failed to decode a public key (ie it's invalid)
        BadPublicKey,
        /// Failed to decode a signature (ie it's invalid)
@@ -510,6 +512,7 @@ impl Error for DecodeError {
        fn description(&self) -> &str {
                match *self {
                        DecodeError::UnknownRealmByte => "Unknown realm byte in Onion packet",
+                       DecodeError::UnknownRequiredFeature => "Unknown required feature preventing decode",
                        DecodeError::BadPublicKey => "Invalid public key in packet",
                        DecodeError::BadSignature => "Invalid signature in packet",
                        DecodeError::BadText => "Invalid text in packet",
@@ -1197,6 +1200,10 @@ impl MsgEncodable for AnnouncementSignatures {
 impl MsgDecodable for UnsignedNodeAnnouncement {
        fn decode(v: &[u8]) -> Result<Self, DecodeError> {
                let features = GlobalFeatures::decode(&v[..])?;
+               if features.requires_unknown_bits() {
+                       return Err(DecodeError::UnknownRequiredFeature);
+               }
+
                if v.len() < features.encoded_len() + 4 + 33 + 3 + 32 + 2 {
                        return Err(DecodeError::ShortRead);
                }
@@ -1380,6 +1387,9 @@ impl MsgEncodable for NodeAnnouncement {
 impl MsgDecodable for UnsignedChannelAnnouncement {
        fn decode(v: &[u8]) -> Result<Self, DecodeError> {
                let features = GlobalFeatures::decode(&v[..])?;
+               if features.requires_unknown_bits() {
+                       return Err(DecodeError::UnknownRequiredFeature);
+               }
                if v.len() < features.encoded_len() + 32 + 8 + 33*4 {
                        return Err(DecodeError::ShortRead);
                }
index 7af4c0e29f2c1f36f38f71237b01ae5e0fb91a20..9d5f58d7fb861b5898a08b331ccf2b1680acef21 100644 (file)
@@ -334,6 +334,10 @@ impl<Descriptor: SocketDescriptor> PeerManager<Descriptor> {
                                                                                Err(e) => {
                                                                                        match e {
                                                                                                msgs::DecodeError::UnknownRealmByte => return Err(PeerHandleError{ no_connection_possible: false }),
+                                                                                               msgs::DecodeError::UnknownRequiredFeature => {
+                                                                                                       log_debug!(self, "Got a channel/node announcement with an known required feature flag, you may want to udpate!");
+                                                                                                       continue;
+                                                                                               },
                                                                                                msgs::DecodeError::BadPublicKey => return Err(PeerHandleError{ no_connection_possible: false }),
                                                                                                msgs::DecodeError::BadSignature => return Err(PeerHandleError{ no_connection_possible: false }),
                                                                                                msgs::DecodeError::BadText => return Err(PeerHandleError{ no_connection_possible: false }),
index 1f713f69de8287fd298776179c51c3f4389e69be..5f0cff3cdcff00b943d9232990a5d236fe8b0390 100644 (file)
@@ -172,6 +172,10 @@ impl RoutingMessageHandler for Router {
                let msg_hash = Message::from_slice(&Sha256dHash::from_data(&msg.contents.encode()[..])[..]).unwrap();
                secp_verify_sig!(self.secp_ctx, &msg_hash, &msg.signature, &msg.contents.node_id);
 
+               if msg.contents.features.requires_unknown_bits() {
+                       panic!("Unknown-required-features NodeAnnouncements should never deserialize!");
+               }
+
                let mut network = self.network_map.write().unwrap();
                match network.nodes.get_mut(&msg.contents.node_id) {
                        None => Err(HandleError{err: "No existing channels for node_announcement", action: Some(ErrorAction::IgnoreError)}),
@@ -201,7 +205,7 @@ impl RoutingMessageHandler for Router {
                //TODO: Only allow bitcoin chain_hash
 
                if msg.contents.features.requires_unknown_bits() {
-                       return Err(HandleError{err: "Channel announcement required unknown feature flags", action: None});
+                       panic!("Unknown-required-features ChannelAnnouncements should never deserialize!");
                }
 
                let mut network = self.network_map.write().unwrap();