What changed, and why it matters
This commit fixes two bugs in the Bitcoin PSBT (Partially Signed Bitcoin Transaction) handling code of a hardware wallet firmware. One fix corrects the order of arguments passed between C and Rust code so they match the expected function signature. The other fix moves the array-size assignment to happen before the array is populated, ensuring all nine public keys are properly registered instead of only the first four. These are likely functional bugs that could cause transaction parsing or signing to fail or behave incorrectly, but the diff alone does not prove a direct theft-of-funds vulnerability.
Review the full call sites of `utxo_parse_extend_psbt` to confirm no other mismatched signatures remain, and verify that all nine extended public keys are now correctly visible to the Rust PSBT parser. Consider adding regression tests or static assertions for FFI signature alignment and array-size initialization order.
Security signals we found
Foreign Function Interface (FFI) parameter mismatch corrected
Array size set before population rather than after partial population
Potential use of stale or incorrect public-key metadata during PSBT parsing
Fixes a bug that could affect transaction validation or signing correctness
Evidence from the diff
The patch modifies rust/rust_c/src/bitcoin/psbt.rs to reorder parameters in utxo_parse_extend_psbt so public_keys precedes master_fingerprint and length, matching the C caller. In src/ui/gui_chain/gui_btc.c, it moves public_keys->size = NUMBER_OF_ARRAYS(keys) from after the first four keys to immediately after keys is declared and assigned, so the size reflects all nine entries before they are filled. The prior code set size to 4, then later overwrote it with 9 after only four Bitcoin keys had been assigned; the remaining five keys (AVAX, etc.) were added after the size assignment. This could lead to the Rust side reading only four keys or reading uninitialized/garbage data for the later entries depending on exact call timing and memory layout.
Changed components
Bitcoin PSBT parsing Rust module (rust/rust_c/src/bitcoin/psbt.rs)Bitcoin GUI chain C module (src/ui/gui_chain/gui_btc.c)C/Rust FFI boundary for extended public key handlingInspect captured patch +2 / −3
diff --git a/rust/rust_c/src/bitcoin/psbt.rs b/rust/rust_c/src/bitcoin/psbt.rs
index e3221a0..4728df0 100644
--- a/rust/rust_c/src/bitcoin/psbt.rs
+++ b/rust/rust_c/src/bitcoin/psbt.rs
@@ -57,9 +57,9 @@ pub extern "C" fn btc_parse_psbt(
#[no_mangle]
pub extern "C" fn utxo_parse_extend_psbt(
ptr: PtrUR,
+ public_keys: PtrT<CSliceFFI<ExtendedPublicKey>>,
master_fingerprint: PtrBytes,
length: u32,
- public_keys: PtrT<CSliceFFI<ExtendedPublicKey>>,
) -> *mut TransactionParseResult<DisplayTx> {
if length != 4 {
return TransactionParseResult::from(RustCError::InvalidMasterFingerprint).c_ptr();
diff --git a/src/ui/gui_chain/gui_btc.c b/src/ui/gui_chain/gui_btc.c
index b85e668..972cec7 100644
--- a/src/ui/gui_chain/gui_btc.c
+++ b/src/ui/gui_chain/gui_btc.c
@@ -653,7 +653,7 @@ PtrT_TransactionCheckResult GuiGetPsbtCheckResult(void)
PtrT_CSliceFFI_ExtendedPublicKey public_keys = SRAM_MALLOC(sizeof(CSliceFFI_ExtendedPublicKey));
ExtendedPublicKey keys[9];
public_keys->data = keys;
- public_keys->size = 4;
+ public_keys->size = NUMBER_OF_ARRAYS(keys);
keys[0].path = "m/84'/0'/0'";
keys[0].xpub = GetCurrentAccountPublicKey(XPUB_TYPE_BTC_NATIVE_SEGWIT);
keys[1].path = "m/49'/0'/0'";
@@ -662,7 +662,6 @@ PtrT_TransactionCheckResult GuiGetPsbtCheckResult(void)
keys[2].xpub = GetCurrentAccountPublicKey(XPUB_TYPE_BTC_LEGACY);
keys[3].path = "m/86'/0'/0'";
keys[3].xpub = GetCurrentAccountPublicKey(XPUB_TYPE_BTC_TAPROOT);
- public_keys->size = NUMBER_OF_ARRAYS(keys);
keys[4].path = "m/44'/60'/0'";
keys[4].xpub = GetCurrentAccountPublicKey(XPUB_TYPE_AVAX_BIP44_STANDARD);
keys[5].path = "m/44'/3'/0'";
Why this scored 45/100
Community notes
Notes can correct, qualify, or add evidence to the AI analysis. Every note shown here has been validated by a human moderator.
The AI analysis stands alone for now. Submit a note if you can add evidence or important context.