Skip to content

Commit 77b104e

Browse files
committed
Merge rust-bitcoin#5500: Fix bug in Psbt::spend_utxo when missing output
164a9a5 Fix bug in `Psbt::spend_utxo` when missing output (Shing Him Ng) Pull request description: Something else found from fuzzing: ``` thread '<unnamed>' (8730670) panicked at bitcoin/src/psbt/mod.rs:625:38: index out of bounds: the len is 0 but the index is 16765184 note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace ==1660== ERROR: libFuzzer: deadly signal #0 0x000104e693c4 in __sanitizer_print_stack_trace+0x28 (librustc-nightly_rt.asan.dylib:arm64+0x5d3c4) #1 0x000104439f6c in fuzzer::PrintStackTrace()+0x30 (bitcoin_arbitrary_psbt:arm64+0x100399f6c) #2 0x00010442e450 in fuzzer::Fuzzer::CrashCallback()+0x54 (bitcoin_arbitrary_psbt:arm64+0x10038e450) #3 0x00019914f740 in _sigtramp+0x34 (libsystem_platform.dylib:arm64+0x3740) #4 0x000199145884 in pthread_kill+0x124 (libsystem_pthread.dylib:arm64+0x6884) #5 0x00019904a84c in abort+0x78 (libsystem_c.dylib:arm64+0x7984c) #6 0x0001044b59f8 in _RNvNtNtNtCsk9AQ7OSayGk_3std3sys3pal4unix14abort_internal+0x8 (bitcoin_arbitrary_psbt:arm64+0x1004159f8) #7 0x0001044b5854 in _RNvNtCsk9AQ7OSayGk_3std7process5abort+0x8 (bitcoin_arbitrary_psbt:arm64+0x100415854) #8 0x0001044b0a30 in _RNCNvCsaBYAWE6hvc2_13libfuzzer_sys10initialize0B3_+0xb8 (bitcoin_arbitrary_psbt:arm64+0x100410a30) rust-bitcoin#9 0x0001044891bc in _RNvNtCsk9AQ7OSayGk_3std9panicking15panic_with_hook+0x264 (bitcoin_arbitrary_psbt:arm64+0x1003e91bc) rust-bitcoin#10 0x00010447d1f0 in _RNCNvNtCsk9AQ7OSayGk_3std9panicking13panic_handler0B5_+0x40 (bitcoin_arbitrary_psbt:arm64+0x1003dd1f0) rust-bitcoin#11 0x000104474b78 in _RINvNtNtCsk9AQ7OSayGk_3std3sys9backtrace26___rust_end_short_backtraceNCNvNtB6_9panicking13panic_handler0zEB6_+0x8 (bitcoin_arbitrary_psbt:arm64+0x1003d4b78) rust-bitcoin#12 0x00010447d800 in _RNvCseYE12Li5r0M_7___rustc17rust_begin_unwind+0x1c (bitcoin_arbitrary_psbt:arm64+0x1003dd800) rust-bitcoin#13 0x0001044b6150 in _RNvNtCsh0x4TIixgmZ_4core9panicking9panic_fmt+0x24 (bitcoin_arbitrary_psbt:arm64+0x100416150) rust-bitcoin#14 0x0001044b5f98 in _RNvNtCsh0x4TIixgmZ_4core9panicking18panic_bounds_check+0x34 (bitcoin_arbitrary_psbt:arm64+0x100415f98) rust-bitcoin#15 0x0001041bd2ac in _RNvMNtCs9rLNVcx1A2L_7bitcoin4psbtNtB2_4Psbt10spend_utxo+0x558 (bitcoin_arbitrary_psbt:arm64+0x10011d2ac) rust-bitcoin#16 0x0001040ebc3c in _RNvNvCshHXwvrCOqYg_22bitcoin_arbitrary_psbt1__19___libfuzzer_sys_run arbitrary_psbt.rs:41 rust-bitcoin#17 0x0001040f73cc in rust_fuzzer_test_input lib.rs:276 rust-bitcoin#18 0x00010442ca04 in _RINvNvNtCsk9AQ7OSayGk_3std9panicking12catch_unwind7do_callNCNvCsaBYAWE6hvc2_13libfuzzer_sys15test_input_wrap0lEBY_+0xc4 (bitcoin_arbitrary_psbt:arm64+0x10038ca04) rust-bitcoin#19 0x00010442d6cc in __rust_try+0x18 (bitcoin_arbitrary_psbt:arm64+0x10038d6cc) rust-bitcoin#20 0x00010442c304 in LLVMFuzzerTestOneInput+0x16c (bitcoin_arbitrary_psbt:arm64+0x10038c304) rust-bitcoin#21 0x00010442fd08 in fuzzer::Fuzzer::ExecuteCallback(unsigned char const*, unsigned long)+0x158 (bitcoin_arbitrary_psbt:arm64+0x10038fd08) rust-bitcoin#22 0x00010444b1c8 in fuzzer::RunOneTest(fuzzer::Fuzzer*, char const*, unsigned long)+0xd8 (bitcoin_arbitrary_psbt:arm64+0x1003ab1c8) rust-bitcoin#23 0x00010444fe38 in fuzzer::FuzzerDriver(int*, char***, int (*)(unsigned char const*, unsigned long))+0x1b8c (bitcoin_arbitrary_psbt:arm64+0x1003afe38) rust-bitcoin#24 0x00010445c7f0 in main+0x24 (bitcoin_arbitrary_psbt:arm64+0x1003bc7f0) rust-bitcoin#25 0x000198d7dd50 (<unknown module>) NOTE: libFuzzer has rudimentary signal handlers. Combine libFuzzer with AddressSanitizer or similar for better crash reports. SUMMARY: libFuzzer: deadly signal ──────────────────────────────────────────────────────────────────────────────── ``` ACKs for top commit: tcharding: ACK 164a9a5 apoelstra: ACK 164a9a5; successfully ran local tests Tree-SHA512: 617843b541ecd19ade2a6dc9d449e7a5267f3f1e6c7749db16afd5d523d99dc978e43652711a3f02b2c04c94c7e6c464535e922bc0767b4a94180a0e12411ddc
2 parents ed6fcfd + 164a9a5 commit 77b104e

File tree

1 file changed

+47
-1
lines changed

1 file changed

+47
-1
lines changed

bitcoin/src/psbt/mod.rs

Lines changed: 47 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -621,7 +621,7 @@ impl Psbt {
621621
witness_utxo
622622
} else if let Some(non_witness_utxo) = &input.non_witness_utxo {
623623
let vout = self.unsigned_tx.inputs[input_index].previous_output.vout;
624-
&non_witness_utxo.outputs[vout as usize]
624+
non_witness_utxo.outputs.get(vout as usize).ok_or(SignError::MissingSpendUtxo)?
625625
} else {
626626
return Err(SignError::MissingSpendUtxo);
627627
};
@@ -2557,6 +2557,52 @@ mod tests {
25572557
Err(ExtractTxError::MissingInputAmount { tx: _ })
25582558
))
25592559
}
2560+
2561+
#[test]
2562+
fn spending_psbt_with_missing_txout() {
2563+
let psbt = Psbt {
2564+
unsigned_tx: Transaction {
2565+
version: transaction::Version::TWO,
2566+
lock_time: absolute::LockTime::from_consensus(1257139),
2567+
inputs: vec![TxIn {
2568+
previous_output: OutPoint {
2569+
txid: "f61b1742ca13176464adb3cb66050c00787bb3a4eead37e985f2df1e37718126"
2570+
.parse()
2571+
.unwrap(),
2572+
vout: 0,
2573+
},
2574+
script_sig: ScriptSigBuf::new(),
2575+
sequence: Sequence::ENABLE_LOCKTIME_NO_RBF,
2576+
witness: Witness::default(),
2577+
}],
2578+
outputs: vec![
2579+
TxOut {
2580+
amount: Amount::from_sat_u32(99_999_699),
2581+
script_pubkey: ScriptPubKeyBuf::from_hex_no_length_prefix(
2582+
"76a914d0c59903c5bac2868760e90fd521a4665aa7652088ac",
2583+
)
2584+
.unwrap(),
2585+
},
2586+
],
2587+
},
2588+
xpub: Default::default(),
2589+
version: 0,
2590+
proprietary: Default::default(),
2591+
unknown: Default::default(),
2592+
inputs: vec![Input {
2593+
non_witness_utxo: Some(Transaction {
2594+
version: transaction::Version::TWO,
2595+
lock_time: absolute::LockTime::ZERO,
2596+
inputs: vec![],
2597+
outputs: vec![], // No outputs here
2598+
}),
2599+
..Default::default()
2600+
}],
2601+
outputs: vec![Output::default()],
2602+
};
2603+
2604+
assert!(matches!(psbt.spend_utxo(0), Err(SignError::MissingSpendUtxo)))
2605+
}
25602606

25612607
#[test]
25622608
#[cfg(all(feature = "rand", feature = "std"))]

0 commit comments

Comments
 (0)