Skip to content

Makes ChannelManager::force_close_channel fail for unknown chan_ids #777

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Jan 25, 2021

Conversation

sr-gi
Copy link
Contributor

@sr-gi sr-gi commented Jan 14, 2021

ChannelManager::force_close_channel does not fail if a non-existing channel id is being passed, making it hard to catch from an API point of view.

Makes force_close_channel return in the same way close_channel does so the user calling the method with an unknown id can be warned.

There's a couple of things that may need fixing:

  • There's currently no testing of this anywhere, since I haven't found any unit testing or similar. I can add it if I missed it.
  • I was unsure if the c-bindings need to be recreated for every change, or if you do right before a new release.

close #773

@sr-gi sr-gi force-pushed the cm-force-close-checks branch from 75d9ee0 to e6e0cf6 Compare January 14, 2021 16:17
@codecov
Copy link

codecov bot commented Jan 14, 2021

Codecov Report

Merging #777 (2869543) into main (d529a88) will decrease coverage by 0.00%.
The diff coverage is 95.87%.

Impacted file tree graph

@@            Coverage Diff             @@
##             main     #777      +/-   ##
==========================================
- Coverage   91.24%   91.24%   -0.01%     
==========================================
  Files          37       37              
  Lines       22866    22847      -19     
==========================================
- Hits        20865    20846      -19     
  Misses       2001     2001              
Impacted Files Coverage Δ
lightning/src/ln/channel.rs 87.49% <ø> (ø)
lightning/src/ln/channelmanager.rs 84.99% <60.00%> (+0.05%) ⬆️
lightning/src/ln/onchaintx.rs 94.02% <95.45%> (+0.09%) ⬆️
lightning/src/chain/channelmonitor.rs 95.81% <100.00%> (+0.13%) ⬆️
lightning/src/chain/keysinterface.rs 93.29% <100.00%> (-0.05%) ⬇️
lightning/src/ln/chanmon_update_fail_tests.rs 97.56% <100.00%> (ø)
lightning/src/ln/functional_tests.rs 96.93% <100.00%> (-0.07%) ⬇️
lightning/src/util/enforcing_trait_impls.rs 100.00% <100.00%> (ø)

Continue to review full report at Codecov.

Legend - Click here to learn more
Δ = absolute <relative> (impact), ø = not affected, ? = missing data
Powered by Codecov. Last update d529a88...821f6cd. Read the comment docs.

}

/// Force close all channels, immediately broadcasting the latest local commitment transaction
/// for each to the chain and rejecting new HTLCs on each.
pub fn force_close_all_channels(&self) {
for chan in self.list_channels() {
self.force_close_channel(&chan.channel_id);
self.force_close_channel(&chan.channel_id).unwrap();
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is race-y - if we close a channel in another thread while this is running we'll panic needlessly.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Rebased in 0e83723

@@ -918,7 +918,7 @@ impl<ChanSigner: ChannelKeys, M: Deref, T: Deref, K: Deref, F: Deref, L: Deref>

/// Force closes a channel, immediately broadcasting the latest local commitment transaction to
/// the chain and rejecting new HTLCs on the given channel.
pub fn force_close_channel(&self, channel_id: &[u8; 32]) {
pub fn force_close_channel(&self, channel_id: &[u8; 32]) -> Result<(), APIError>{
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It would be nice to update the docs here to state that we only fail in case the channel is not found.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Rebased in 0e83723

@sr-gi sr-gi force-pushed the cm-force-close-checks branch from e6e0cf6 to 0e83723 Compare January 15, 2021 11:45
}
}
} else {
self.force_close_channel(&msg.channel_id);
self.force_close_channel(&msg.channel_id).unwrap();
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This handles an untrusted message from a peer - if they send us a garbage channel_id we shouldn't crash.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ups, didn't realize that came from a peer.

Rebased in 03a72f1

@@ -3471,11 +3473,11 @@ impl<ChanSigner: ChannelKeys, M: Deref + Sync + Send, T: Deref + Sync + Send, K:
if msg.channel_id == [0; 32] {
for chan in self.list_channels() {
if chan.remote_network_id == *counterparty_node_id {
self.force_close_channel(&chan.channel_id);
self.force_close_channel(&chan.channel_id).unwrap();
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is also race-y, I believe.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Rebased in 03a72f1

@sr-gi sr-gi force-pushed the cm-force-close-checks branch from 0e83723 to 03a72f1 Compare January 18, 2021 09:35
Copy link

@ariard ariard left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ACK-modulo-adding-warning-comment.

@@ -3471,11 +3473,11 @@ impl<ChanSigner: ChannelKeys, M: Deref + Sync + Send, T: Deref + Sync + Send, K:
if msg.channel_id == [0; 32] {
for chan in self.list_channels() {
if chan.remote_network_id == *counterparty_node_id {
self.force_close_channel(&chan.channel_id);
let _ = self.force_close_channel(&msg.channel_id);
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can you add a code comment here and below : "Untrusted messages from peer, we throw away the error if id points to a non-existent channel". A good warning to avoid vulns in in case of new work around this code path.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Added in 821f6cd

ChannelManager::force_close_channel does not fail if a non-existing channel id is being passed, making it hard to catch from an API point of view.

Makes force_close_channel return in the same way close_channel does so the user calling the method with an unknown id can be warned.
@sr-gi sr-gi force-pushed the cm-force-close-checks branch from 03a72f1 to 821f6cd Compare January 21, 2021 15:13
@TheBlueMatt TheBlueMatt merged commit 25c9a37 into lightningdevkit:main Jan 25, 2021
TheBlueMatt added a commit to TheBlueMatt/rust-lightning that referenced this pull request Feb 3, 2021
When we receive an error message from a peer, it can indicate a
channel which we should close. However, we previously did not
check that the counterparty who sends us such a message is the
counterparty with whom we have the channel, allowing any
connected peer to make us force-close any channel we have as long
as they know the channel id.

This commit simply changes the force-close logic to check that the
sender matches the channel's counterparty node_id, though as noted
in lightningdevkit#105, we eventually need to change the indexing anyway to allow
absurdly terrible peers to open channels with us.

Found during review of lightningdevkit#777.
TheBlueMatt added a commit to TheBlueMatt/rust-lightning that referenced this pull request Feb 7, 2021
When we receive an error message from a peer, it can indicate a
channel which we should close. However, we previously did not
check that the counterparty who sends us such a message is the
counterparty with whom we have the channel, allowing any
connected peer to make us force-close any channel we have as long
as they know the channel id.

This commit simply changes the force-close logic to check that the
sender matches the channel's counterparty node_id, though as noted
in lightningdevkit#105, we eventually need to change the indexing anyway to allow
absurdly terrible peers to open channels with us.

Found during review of lightningdevkit#777.
TheBlueMatt added a commit to TheBlueMatt/rust-lightning that referenced this pull request Feb 10, 2021
When we receive an error message from a peer, it can indicate a
channel which we should close. However, we previously did not
check that the counterparty who sends us such a message is the
counterparty with whom we have the channel, allowing any
connected peer to make us force-close any channel we have as long
as they know the channel id.

This commit simply changes the force-close logic to check that the
sender matches the channel's counterparty node_id, though as noted
in lightningdevkit#105, we eventually need to change the indexing anyway to allow
absurdly terrible peers to open channels with us.

Found during review of lightningdevkit#777.
valentinewallace pushed a commit to valentinewallace/rust-lightning that referenced this pull request Feb 18, 2021
When we receive an error message from a peer, it can indicate a
channel which we should close. However, we previously did not
check that the counterparty who sends us such a message is the
counterparty with whom we have the channel, allowing any
connected peer to make us force-close any channel we have as long
as they know the channel id.

This commit simply changes the force-close logic to check that the
sender matches the channel's counterparty node_id, though as noted
in lightningdevkit#105, we eventually need to change the indexing anyway to allow
absurdly terrible peers to open channels with us.

Found during review of lightningdevkit#777.
valentinewallace pushed a commit to valentinewallace/rust-lightning that referenced this pull request Feb 19, 2021
When we receive an error message from a peer, it can indicate a
channel which we should close. However, we previously did not
check that the counterparty who sends us such a message is the
counterparty with whom we have the channel, allowing any
connected peer to make us force-close any channel we have as long
as they know the channel id.

This commit simply changes the force-close logic to check that the
sender matches the channel's counterparty node_id, though as noted
in lightningdevkit#105, we eventually need to change the indexing anyway to allow
absurdly terrible peers to open channels with us.

Found during review of lightningdevkit#777.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

ChannelManager::force_close_channel does not fail on random channel_id
3 participants