Skip to content

Commit 2826af7

Browse files
committed
Reject channels if the total reserves are larger than the funding
The `full_stack_target` fuzzer managed to find a subtraction underflow in the new `Channel::get_htlc_maximum` function where we subtract both sides' reserve values from the channel funding. Such a channel is obviously completely useless, so we should reject it during opening instead of integer-underflowing later. Thanks to Chaincode Labs for providing the fuzzing resources which found this bug!
1 parent d1b984d commit 2826af7

File tree

1 file changed

+6
-4
lines changed

1 file changed

+6
-4
lines changed

lightning/src/ln/channel.rs

+6-4
Original file line numberDiff line numberDiff line change
@@ -1082,14 +1082,13 @@ impl<Signer: Sign> Channel<Signer> {
10821082
if msg.channel_reserve_satoshis > msg.funding_satoshis {
10831083
return Err(ChannelError::Close(format!("Bogus channel_reserve_satoshis ({}). Must be not greater than funding_satoshis: {}", msg.channel_reserve_satoshis, msg.funding_satoshis)));
10841084
}
1085-
let funding_value = (msg.funding_satoshis - msg.channel_reserve_satoshis) * 1000;
1086-
if msg.push_msat > funding_value {
1087-
return Err(ChannelError::Close(format!("push_msat {} was larger than funding value {}", msg.push_msat, funding_value)));
1085+
let full_channel_value_msat = (msg.funding_satoshis - msg.channel_reserve_satoshis) * 1000;
1086+
if msg.push_msat > full_channel_value_msat {
1087+
return Err(ChannelError::Close(format!("push_msat {} was larger than funding value {}", msg.push_msat, full_channel_value_msat)));
10881088
}
10891089
if msg.dust_limit_satoshis > msg.funding_satoshis {
10901090
return Err(ChannelError::Close(format!("dust_limit_satoshis {} was larger than funding_satoshis {}. Peer never wants payout outputs?", msg.dust_limit_satoshis, msg.funding_satoshis)));
10911091
}
1092-
let full_channel_value_msat = (msg.funding_satoshis - msg.channel_reserve_satoshis) * 1000;
10931092
if msg.htlc_minimum_msat >= full_channel_value_msat {
10941093
return Err(ChannelError::Close(format!("Minimum htlc value ({}) was larger than full channel value ({})", msg.htlc_minimum_msat, full_channel_value_msat)));
10951094
}
@@ -1143,6 +1142,9 @@ impl<Signer: Sign> Channel<Signer> {
11431142
if holder_selected_channel_reserve_satoshis < MIN_CHAN_DUST_LIMIT_SATOSHIS {
11441143
return Err(ChannelError::Close(format!("Suitable channel reserve not found. remote_channel_reserve was ({}). dust_limit_satoshis is ({}).", holder_selected_channel_reserve_satoshis, MIN_CHAN_DUST_LIMIT_SATOSHIS)));
11451144
}
1145+
if holder_selected_channel_reserve_satoshis * 1000 >= full_channel_value_msat {
1146+
return Err(ChannelError::Close(format!("Suitable channel reserve not found. remote_channel_reserve was ({}). Channel value is ({} - {}).", holder_selected_channel_reserve_satoshis, full_channel_value_msat, msg.push_msat)));
1147+
}
11461148
if msg.channel_reserve_satoshis < MIN_CHAN_DUST_LIMIT_SATOSHIS {
11471149
log_debug!(logger, "channel_reserve_satoshis ({}) is smaller than our dust limit ({}). We can broadcast stale states without any risk, implying this channel is very insecure for our counterparty.",
11481150
msg.channel_reserve_satoshis, MIN_CHAN_DUST_LIMIT_SATOSHIS);

0 commit comments

Comments
 (0)