What changed, and why it matters
This commit fixes a bug in the Unix emulator for Trezor's USB virtual serial port (VCP). Previously, after reading part of a message, the emulator would erase the entire buffer and reset the length to zero, even if unread data remained. Now, for VCP interfaces, it correctly keeps the unread portion of the message for the next read. This is a correctness fix in emulator code, not the real device firmware, and there is no direct evidence it is security-relevant or exploitable.
Treat as a normal bug fix. No urgent security action is indicated. If using the Unix emulator for VCP-based workflows, ensure this patch is included to avoid message truncation. No CVE or advisory appears warranted based on the supplied materials.
Security signals we found
Behavioral correctness fix in USB message handling
Potential data loss / truncation in emulator VCP reads before fix
No direct memory corruption, overflow, or authentication bypass evident
Evidence from the diff
The patch modifies usb_emulated_read() in core/embed/io/usb/unix/usb.c. Before the fix, every successful read path set iface->msg_len = 0 and memzero’d the full iface->msg buffer, discarding any data beyond the requested read length. For USB_IFACE_TYPE_VCP, this is incorrect because VCP reads can be partial and the remaining bytes should be preserved for subsequent reads. The fix branches on iface->type: for VCP it memmove’s the remaining bytes to the front and decrements msg_len; for other interface types it keeps the old clear-all behavior. This is a functional bug in the Unix host emulation layer, not a memory-safety defect in the embedded firmware.
Changed components
core/embed/io/usb/unix/usb.cUSB VCP emulation on Unix build targetsInspect captured patch +8 / −2
diff --git a/core/embed/io/usb/unix/usb.c b/core/embed/io/usb/unix/usb.c
index 658d82fc4..b45a7553a 100644
--- a/core/embed/io/usb/unix/usb.c
+++ b/core/embed/io/usb/unix/usb.c
@@ -224,8 +224,14 @@ static int usb_emulated_read(usb_iface_t *iface, uint8_t *buf, uint32_t len) {
len = iface->msg_len;
}
memcpy(buf, iface->msg, len);
- iface->msg_len = 0;
- memzero(iface->msg, sizeof(iface->msg));
+
+ if (iface->type == USB_IFACE_TYPE_VCP) {
+ iface->msg_len -= len;
+ memmove(iface->msg, iface->msg + len, iface->msg_len);
+ } else {
+ iface->msg_len = 0;
+ memzero(iface->msg, sizeof(iface->msg));
+ }
return len;
}
Why this scored 27/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.