Don't unwrap() get_channel_update result in HTLC router
authorMatt Corallo <git@bluematt.me>
Sun, 18 Nov 2018 21:15:08 +0000 (16:15 -0500)
committerMatt Corallo <git@bluematt.me>
Sun, 18 Nov 2018 21:17:06 +0000 (16:17 -0500)
This fixes a bug in 78232f2aeded08b32fa4ebfeb0b77d80b337518d found
by fuzzer - if the channel isn't yet fully established we will call
get_channel_update(), get an Err result, and then unwrap() it. If
this actually happens it means someone on the network is making up
short_channel_ids and trying to route over them, but that shouldn't
result in us crashing

src/ln/channelmanager.rs

index dab22d286cc5581422f861e91c97f6b2a4b96e40..c3d39d8f85498508468c771d21a690a26891a351 100644 (file)
@@ -1942,10 +1942,20 @@ impl ChannelManager {
                                        // but if we've sent a shutdown and they haven't acknowledged it yet, we just
                                        // want to reject the new HTLC and fail it backwards instead of forwarding.
                                        if let PendingHTLCStatus::Forward(PendingForwardHTLCInfo { incoming_shared_secret, .. }) = pending_forward_info {
+                                               let chan_update = self.get_channel_update(chan);
                                                pending_forward_info = PendingHTLCStatus::Fail(HTLCFailureMsg::Relay(msgs::UpdateFailHTLC {
                                                        channel_id: msg.channel_id,
                                                        htlc_id: msg.htlc_id,
-                                                       reason: ChannelManager::build_first_hop_failure_packet(&incoming_shared_secret, 0x1000|20, &self.get_channel_update(chan).unwrap().encode_with_len()[..]),
+                                                       reason: if let Ok(update) = chan_update {
+                                                               ChannelManager::build_first_hop_failure_packet(&incoming_shared_secret, 0x1000|20, &update.encode_with_len()[..])
+                                                       } else {
+                                                               // This can only happen if the channel isn't in the fully-funded
+                                                               // state yet, implying our counterparty is trying to route payments
+                                                               // over the channel back to themselves (cause no one else should
+                                                               // know the short_id is a lightning channel yet). We should have no
+                                                               // problem just calling this unknown_next_peer
+                                                               ChannelManager::build_first_hop_failure_packet(&incoming_shared_secret, 0x4000|10, &[])
+                                                       },
                                                }));
                                        }
                                }