What changed, and why it matters
This commit changes how Trezor firmware handles Ethereum transaction data (calldata). Previously, the code only tried to 'clear sign' transactions where the entire calldata fit in the first chunk. Now it stores and processes up to 4 KB of calldata across multiple chunks, and gives up gracefully if the data is too large. The change appears to be a hardening/capacity improvement rather than a fix for an active exploit, but it removes a risky assumption that all data is present in the initial chunk.
Review whether the 4 KB limit and truncation handling are consistent with the Ethereum message protocol's chunk size and total data_length. Verify that the claimed unreachable OutOfBounds path is indeed unreachable across all firmware variants and that no integer/bounds issue exists in the new arithmetic. Consider whether this change warrants a changelog/security note despite the [no changelog] marker.
Security signals we found
Bounds/limit introduced on stored calldata size
Truncation flag added with defensive exception path
Clear-signing now gated on data_length <= 4096 instead of equality with initial chunk
Comment claims truncation path cannot be reached because data_length is checked earlier
No changelog entry; commit framed as routine chore
Evidence from the diff
The patch modifies core/src/apps/ethereum/clear_signing.py. It introduces a MAX_CALLDATA_STORED limit of 4096 bytes and a ParsingContext.truncated flag. process_data_chunk now accumulates up to 4 KB of calldata after stripping the 4-byte function selector, sets truncated when the limit is reached, and stops storing further data. get_parameters_and_fields raises OutOfBounds if truncated (defense in depth). get_approver now allows clear signing when data_length <= 4096 instead of requiring the entire calldata to be in data_initial_chunk. The commit message is a routine ‘chore’ with [no changelog].
Changed components
Trezor firmware Ethereum clear signing moduleParsingContext classget_approver functionInspect captured patch +25 / −4
diff --git a/core/src/apps/ethereum/clear_signing.py b/core/src/apps/ethereum/clear_signing.py
index 94e74406..5c9df048 100644
--- a/core/src/apps/ethereum/clear_signing.py
+++ b/core/src/apps/ethereum/clear_signing.py
@@ -30,6 +30,7 @@ if TYPE_CHECKING:
SC_FUNC_SIG_BYTES = const(4)
+MAX_CALLDATA_STORED = const(4096)
class InvalidFunctionCall(Exception):
@@ -438,13 +439,29 @@ class ParsingContext:
def __init__(self, display_format: DisplayFormat) -> None:
self.data = bytes()
self.display_format = display_format
+ self.truncated = False
def process_data_chunk(self, offset: int, chunk: memoryview) -> None:
if offset == 0:
# skip function signature
chunk = chunk[SC_FUNC_SIG_BYTES:]
- self.data += bytes(chunk)
- # TODO: don't keep more than 4 chunks!
+
+ if not chunk:
+ # nothing to process after skipping function signature
+ return
+
+ current_len = len(self.data)
+ if current_len >= MAX_CALLDATA_STORED:
+ self.truncated = True
+ # reached the storage limit. ignore further chunks.
+ return
+
+ remaining = MAX_CALLDATA_STORED - current_len
+ if len(chunk) > remaining:
+ self.truncated = True
+ chunk = chunk[:remaining]
+ if chunk:
+ self.data += bytes(chunk)
def get_parameters_and_fields(
self,
@@ -453,6 +470,10 @@ class ParsingContext:
network: EthereumNetworkInfo,
token: EthereumTokenInfo,
) -> tuple[list[AnyValue], list[StrPropertyType]]:
+ if self.truncated:
+ # this will not happen, because we already checked the data_length
+ # in the very beginning and bailed from clear signing
+ raise OutOfBounds
parameters: list[AnyValue] = []
@@ -527,8 +548,8 @@ def get_approver(
if not address_bytes:
return None
- # only parse the initial chunk for now
- if msg.data_length != len(msg.data_initial_chunk):
+ if msg.data_length > MAX_CALLDATA_STORED:
+ # skip clear signing if the calldata is longer than what we can process
return None
data_reader = BufferReader(msg.data_initial_chunk)
Why this scored 35/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.