From: Jeffrey Czyz Date: Wed, 15 Feb 2023 22:43:41 +0000 (-0600) Subject: Fix amount overflow in Offer parsing and building X-Git-Url: http://git.bitcoin.ninja/?a=commitdiff_plain;h=83d85ad44f5f48616cd2582356a709ef98fb58dd;p=rust-lightning Fix amount overflow in Offer parsing and building An overflow can occur when multiplying the offer amount by the requested quantity when checking if the given amount is enough. Return an error instead of overflowing. --- diff --git a/lightning/src/offers/invoice_request.rs b/lightning/src/offers/invoice_request.rs index cc397f0f9..a1a0520c6 100644 --- a/lightning/src/offers/invoice_request.rs +++ b/lightning/src/offers/invoice_request.rs @@ -828,6 +828,18 @@ mod tests { Ok(_) => panic!("expected error"), Err(e) => assert_eq!(e, SemanticError::MissingAmount), } + + match OfferBuilder::new("foo".into(), recipient_pubkey()) + .amount_msats(1000) + .supported_quantity(Quantity::Unbounded) + .build().unwrap() + .request_invoice(vec![1; 32], payer_pubkey()).unwrap() + .quantity(u64::max_value()).unwrap() + .build() + { + Ok(_) => panic!("expected error"), + Err(e) => assert_eq!(e, SemanticError::InvalidAmount), + } } #[test] @@ -1123,6 +1135,23 @@ mod tests { assert_eq!(e, ParseError::InvalidSemantics(SemanticError::UnsupportedCurrency)); }, } + + let invoice_request = OfferBuilder::new("foo".into(), recipient_pubkey()) + .amount_msats(1000) + .supported_quantity(Quantity::Unbounded) + .build().unwrap() + .request_invoice(vec![1; 32], payer_pubkey()).unwrap() + .quantity(u64::max_value()).unwrap() + .build_unchecked() + .sign(payer_sign).unwrap(); + + let mut buffer = Vec::new(); + invoice_request.write(&mut buffer).unwrap(); + + match InvoiceRequest::try_from(buffer) { + Ok(_) => panic!("expected error"), + Err(e) => assert_eq!(e, ParseError::InvalidSemantics(SemanticError::InvalidAmount)), + } } #[test] diff --git a/lightning/src/offers/offer.rs b/lightning/src/offers/offer.rs index b0819f9e9..405e2e278 100644 --- a/lightning/src/offers/offer.rs +++ b/lightning/src/offers/offer.rs @@ -431,7 +431,8 @@ impl OfferContents { }; if !self.expects_quantity() || quantity.is_some() { - let expected_amount_msats = offer_amount_msats * quantity.unwrap_or(1); + let expected_amount_msats = offer_amount_msats.checked_mul(quantity.unwrap_or(1)) + .ok_or(SemanticError::InvalidAmount)?; let amount_msats = amount_msats.unwrap_or(expected_amount_msats); if amount_msats < expected_amount_msats {