From 83d85ad44f5f48616cd2582356a709ef98fb58dd Mon Sep 17 00:00:00 2001 From: Jeffrey Czyz Date: Wed, 15 Feb 2023 16:43:41 -0600 Subject: [PATCH] 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. --- lightning/src/offers/invoice_request.rs | 29 +++++++++++++++++++++++++ lightning/src/offers/offer.rs | 3 ++- 2 files changed, 31 insertions(+), 1 deletion(-) 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 { -- 2.39.5