Skip to content

Commit e560ec1

Browse files
Fix underflow in blinded path amt_to_forward
If we have a high (200%+) proportional fee as an intermediate blinded node combined with a low inbound amount, we previously had some code that calculated the outbound amount of the forward that would've underflowed. This would've caused a panic in debug builds and caused us to relay a payment that should've been rejected (due to being unable to cover our high fee) in release builds. Reported by Project Loupe.
1 parent 85a8cb1 commit e560ec1

1 file changed

Lines changed: 16 additions & 1 deletion

File tree

lightning/src/blinded_path/payment.rs

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -940,7 +940,7 @@ pub(crate) fn amt_to_forward_msat(
940940
(post_base_fee_inbound_amt * 1_000_000 + 1_000_000 + prop - 1) / (prop + 1_000_000);
941941

942942
let fee = ((amt_to_forward * prop) / 1_000_000) + base;
943-
if inbound_amt - fee < amt_to_forward {
943+
if inbound_amt.checked_sub(fee)? < amt_to_forward {
944944
// Rounding up the forwarded amount resulted in underpaying this node, so take an extra 1 msat
945945
// in fee to compensate.
946946
amt_to_forward -= 1;
@@ -1415,4 +1415,19 @@ mod tests {
14151415
.unwrap();
14161416
assert_eq!(blinded_payinfo.htlc_maximum_msat, 3997);
14171417
}
1418+
1419+
#[test]
1420+
fn amt_to_forward_msat_underflow() {
1421+
// `amt_to_forward_msat` is documented to return `None` if underflow occurs, but the
1422+
// `inbound_amt - fee` subtraction was previously unguarded. With a high proportional fee
1423+
// and a small inbound amount, rounding the forwarded amount up leaves `fee` larger than
1424+
// `inbound_amt`, so the subtraction underflows (panicking in debug builds and returning a
1425+
// nonsensical result in release). Ensure we instead return `None`.
1426+
let payment_relay = PaymentRelay {
1427+
cltv_expiry_delta: 0,
1428+
fee_proportional_millionths: u32::MAX,
1429+
fee_base_msat: 1,
1430+
};
1431+
assert!(super::amt_to_forward_msat(2, &payment_relay).is_none());
1432+
}
14181433
}

0 commit comments

Comments
 (0)