fix(rust/trezor-thp): do not retransmit before whole message is sent
What changed, and why it matters
This commit fixes a bug in the Trezor hardware wallet's THP (Trezor Host Protocol) Rust code. Previously, the device could start retransmitting a message before it had finished sending all the fragments (pieces) of the current message. The fix makes the device wait until the whole message is sent before it retransmits. This could prevent protocol confusion or errors during communication between the Trezor device and a host computer, especially when retries happen due to network or transport issues.
Treat as a low-to-moderate reliability and potential security hardening fix. Review related THP state machine logic for similar premature retransmission or state-reset issues. No urgent security response is indicated absent further evidence of exploitability.
Security signals we found
Protocol state machine correction
Prevents premature retransmission of incomplete message fragments
Could mitigate denial-of-service or protocol desynchronization during host-device communication
No explicit security disclosure or CVE in commit
Evidence from the diff
In rust/trezor-thp/src/channel/mod.rs, the retransmit logic in ChannelIO::retransmit was reordered and guarded. Previously, the code would reset the fragmenter and increment the retry counter even if the fragmenter had not finished sending all fragments of the current message. The patch moves retry increment to the top and adds an early return if fragmenter.is_done() is false, preventing retransmission before the whole message is sent. This avoids potential interleaving or premature retransmission of incomplete messages in the THP channel layer.
Changed components
rust/trezor-thp/src/channel/mod.rsTrezor Host Protocol (THP) channel layerMessage fragmenter/retransmission logicInspect captured patch +8 / −1
diff --git a/rust/trezor-thp/src/channel/mod.rs b/rust/trezor-thp/src/channel/mod.rs
index d3b7ab93..a730f045 100644
--- a/rust/trezor-thp/src/channel/mod.rs
+++ b/rust/trezor-thp/src/channel/mod.rs
@@ -889,13 +889,20 @@ impl<R: Role, B: Backend> ChannelIO for Channel<R, B> {
log::warn!("[{:04x}] Nothing to retransmit.", self.channel_id);
return Ok(());
};
+ *retry = retry.saturating_add(1);
+ if !fragmenter.is_done() {
+ log::warn!(
+ "[{:04x}] Not retransmitting before all fragments are sent.",
+ self.channel_id
+ );
+ return Ok(());
+ }
log::debug!(
"[{:04x}] Retransmitting message, retry {}.",
self.channel_id,
retry
);
fragmenter.reset();
- *retry = retry.saturating_add(1);
Ok(())
}
Why this scored 42/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.