What changed, and why it matters
This commit fixes an off-by-one-style bounds check in the Ethereum clear-signing code on Trezor hardware wallets. The old check only verified that the starting position was inside the data, but did not verify that the code was about to read 32 bytes from that position. As a result, a malformed Ethereum transaction or message could trick the device into reading past the end of a buffer while decoding human-readable fields. The fix now checks that offset plus 32 bytes does not exceed the data length before reading.
Treat this as a security fix and include it in the next firmware release. Review adjacent parsing methods in clear_signing.py for similar insufficient bounds checks, especially where slices or fixed-size reads follow a simple offset comparison. Consider adding regression tests with crafted short buffers at the boundary.
Security signals we found
Out-of-bounds read prevented by corrected length check
Ethereum clear-signing/ABI parsing code affected
Hardware wallet transaction parsing path involved
No changelog entry supplied by vendor
Evidence from the diff
In core/src/apps/ethereum/clear_signing.py, the Atomic.parse() method reads a 32-byte word from raw_data starting at offset. The original guard was if offset > len(raw_data): raise OutOfBounds, which is insufficient: any offset in [0, len(raw_data)] passes, even when fewer than 32 bytes remain. The patch changes the guard to if offset + 32 > len(raw_data): raise OutOfBounds, ensuring the slice raw_data[offset:offset+32] is fully contained. This is a defensive fix for a potential out-of-bounds read during ABI decoding for Ethereum clear signing.
Changed components
core/src/apps/ethereum/clear_signing.pyTrezor Ethereum clear signing featureAtomic ABI value parserInspect captured patch +1 / −1
diff --git a/core/src/apps/ethereum/clear_signing.py b/core/src/apps/ethereum/clear_signing.py
index c03942a4..976220fe 100644
--- a/core/src/apps/ethereum/clear_signing.py
+++ b/core/src/apps/ethereum/clear_signing.py
@@ -445,7 +445,7 @@ class Atomic(ABIValue):
self.parser = parser
def parse(self, raw_data: memoryview, offset: int) -> tuple[AnyValue, int]:
- if offset > len(raw_data):
+ if offset + 32 > len(raw_data):
raise OutOfBounds
return self.parser(raw_data[offset : offset + 32]), 32
Why this scored 63/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.