fix(python): uncache transport when waiting for the bootloader
What changed, and why it matters
This is a small bug-fix change in the Trezor Python command-line tools. It fixes a situation where the tool would keep using an old cached connection to the device while waiting for the device to reboot into bootloader mode. Now it clears that cached connection and tries to reconnect. There is no direct evidence this is a security vulnerability; it appears to be a reliability/usability fix for firmware updates.
Treat as a routine reliability fix. No urgent security action is indicated by the commit itself. If monitoring, verify the firmware-update CLI behaves correctly across device reboots and does not leave stale file descriptors or connections.
Security signals we found
Fix relates to device connection caching during firmware update workflow
No changelog entry suggests minor/internal fix
No mention of vulnerability, CVE, researcher, or security issue in commit message or diff
Evidence from the diff
The commit modifies TrezorConnection.get_transport() in python/src/trezorlib/cli/__init__.py to accept an optional _clear_cache flag. When true, it unregisters the cached transport’s close handler from atexit, closes the transport, clears the global _TRANSPORT, and then performs a fresh transport lookup. The firmware update command in python/src/trezorlib/cli/firmware.py now calls obj.get_transport(_clear_cache=True) inside its retry loop while waiting for the bootloader. This addresses a stale-transport problem during device reboot for firmware updates. The diff does not show any cryptographic, authentication, or privileged-operation changes.
Changed components
python/src/trezorlib/cli/__init__.pypython/src/trezorlib/cli/firmware.pyInspect captured patch +14 / −4
diff --git a/python/src/trezorlib/cli/__init__.py b/python/src/trezorlib/cli/__init__.py
index be3750ed..1b1d8154 100644
--- a/python/src/trezorlib/cli/__init__.py
+++ b/python/src/trezorlib/cli/__init__.py
@@ -203,11 +203,20 @@ class TrezorConnection:
)
return session
- def get_transport(self) -> "Transport":
+ def get_transport(self, _clear_cache: bool = False) -> "Transport":
global _TRANSPORT
if _TRANSPORT is not None:
- return _TRANSPORT
-
+ if not _clear_cache:
+ return _TRANSPORT
+
+ # remove previously cached transport
+ try:
+ atexit.unregister(_TRANSPORT.close)
+ _TRANSPORT.close()
+ except Exception as e:
+ self._print_exception(e, "Failed to close transport")
+ finally:
+ _TRANSPORT = None
try:
# look for transport without prefix search
_TRANSPORT = transport.get_transport(
diff --git a/python/src/trezorlib/cli/firmware.py b/python/src/trezorlib/cli/firmware.py
index 28a7164d..cea4edb1 100644
--- a/python/src/trezorlib/cli/firmware.py
+++ b/python/src/trezorlib/cli/firmware.py
@@ -736,7 +736,8 @@ def update(
while True:
time.sleep(0.5)
try:
- obj.get_transport()
+ # uncache previous transport to force re-connection attempt
+ obj.get_transport(_clear_cache=True)
break
except Exception:
pass
Why this scored 23/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.