panic!() when serializing OnionHopDatas with value > 21m BTC
authorMatt Corallo <git@bluematt.me>
Sat, 21 Mar 2020 22:49:30 +0000 (18:49 -0400)
committerMatt Corallo <git@bluematt.me>
Wed, 15 Apr 2020 00:50:42 +0000 (20:50 -0400)
Add documentation to the struct fields noting this to avoid missing
docs when various msg structs become public.

lightning/src/ln/msgs.rs

index 4bdde0f4bcb9799913b873443f0e71677b691f45..9698798c22ee0ae79ec24e002ef47220e616e2c4 100644 (file)
@@ -622,6 +622,8 @@ mod fuzzy_internal_msgs {
        #[derive(Clone)]
        pub(crate) struct FinalOnionHopData {
                pub(crate) payment_secret: PaymentSecret,
+               /// The total value, in msat, of the payment as received by the ultimate recipient.
+               /// Message serialization may panic if this value is more than 21 million Bitcoin.
                pub(crate) total_msat: u64,
        }
 
@@ -639,6 +641,8 @@ mod fuzzy_internal_msgs {
 
        pub struct OnionHopData {
                pub(crate) format: OnionHopDataFormat,
+               /// The value, in msat, of the payment after this hop's fee is deducted.
+               /// Message serialization may panic if this value is more than 21 million Bitcoin.
                pub(crate) amt_to_forward: u64,
                pub(crate) outgoing_cltv_value: u32,
                // 12 bytes of 0-padding for Legacy format
@@ -996,6 +1000,10 @@ impl Readable for FinalOnionHopData {
 impl Writeable for OnionHopData {
        fn write<W: Writer>(&self, w: &mut W) -> Result<(), ::std::io::Error> {
                w.size_hint(33);
+               // Note that this should never be reachable if Rust-Lightning generated the message, as we
+               // check values are sane long before we get here, though its possible in the future
+               // user-generated messages may hit this.
+               if self.amt_to_forward > MAX_VALUE_MSAT { panic!("We should never be sending infinite/overflow onion payments"); }
                match self.format {
                        OnionHopDataFormat::Legacy { short_channel_id } => {
                                0u8.write(w)?;
@@ -1012,6 +1020,7 @@ impl Writeable for OnionHopData {
                                });
                        },
                        OnionHopDataFormat::FinalNode { payment_data: Some(ref final_data) } => {
+                               if final_data.total_msat > MAX_VALUE_MSAT { panic!("We should never be sending infinite/overflow onion payments"); }
                                encode_varint_length_prefixed_tlv!(w, {
                                        (2, HighZeroBytesDroppedVarInt(self.amt_to_forward)),
                                        (4, HighZeroBytesDroppedVarInt(self.outgoing_cltv_value)),