From: Matt Corallo Date: Sun, 19 Jan 2020 21:03:25 +0000 (-0500) Subject: Panic on txn with value > 21mill in ChannelMonitor::block_connected X-Git-Url: http://git.bitcoin.ninja/index.cgi?a=commitdiff_plain;h=222c840a83c7df66aaff3a52a3b2c291e6336954;p=rust-lightning Panic on txn with value > 21mill in ChannelMonitor::block_connected full_stack_target found a crash where we may overflow ruring fee calculation if a transaction appears on-chain with massive value available for us to claim. Since these transactions are clearly bogus, we shouldn't allow full_stack_target to connect them, but we also improve the error generated by explicitly panicing on them. --- diff --git a/fuzz/src/full_stack.rs b/fuzz/src/full_stack.rs index 4d1bf5e0b..e29e24ca4 100644 --- a/fuzz/src/full_stack.rs +++ b/fuzz/src/full_stack.rs @@ -487,6 +487,12 @@ pub fn do_test(data: &[u8], logger: &Arc) { } else { let txres: Result = deserialize(get_slice!(txlen)); if let Ok(tx) = txres { + let mut output_val = 0; + for out in tx.output.iter() { + if out.value > 21_000_000_0000_0000 { return; } + output_val += out.value; + if output_val > 21_000_000_0000_0000 { return; } + } loss_detector.connect_block(&[tx]); } else { return; diff --git a/lightning/src/ln/channelmonitor.rs b/lightning/src/ln/channelmonitor.rs index f32d2fbdb..b08b44569 100644 --- a/lightning/src/ln/channelmonitor.rs +++ b/lightning/src/ln/channelmonitor.rs @@ -2335,6 +2335,15 @@ impl ChannelMonitor { } fn block_connected(&mut self, txn_matched: &[&Transaction], height: u32, block_hash: &Sha256dHash, broadcaster: &BroadcasterInterface, fee_estimator: &FeeEstimator)-> (Vec<(Sha256dHash, Vec)>, Vec, Vec<(HTLCSource, Option, PaymentHash)>) { + for tx in txn_matched { + let mut output_val = 0; + for out in tx.output.iter() { + if out.value > 21_000_000_0000_0000 { panic!("Value-overflowing transaction provided to block connected"); } + output_val += out.value; + if output_val > 21_000_000_0000_0000 { panic!("Value-overflowing transaction provided to block connected"); } + } + } + log_trace!(self, "Block {} at height {} connected with {} txn matched", block_hash, height, txn_matched.len()); let mut watch_outputs = Vec::new(); let mut spendable_outputs = Vec::new();