From a187c86890e98cf5799c5e15991687d083b7a3d4 Mon Sep 17 00:00:00 2001 From: Charles-Edouard de la Vergne Date: Tue, 12 May 2026 17:00:48 +0200 Subject: [PATCH 01/29] fix: Bound MAP_ENTRY descriptor list to prevent memory pool DoS verify_map_entry_struct() appended every validly-signed map entry to g_map_entry_list without bound. The list is cleared on reset_app_context() between transactions, so the growth isn't permanent, but a host with N legitimately-signed descriptors can call INS_PROVIDE_MAP_ENTRY repeatedly during a single signing flow and exhaust the shared app-memory pool, denying allocation to other features (trusted_name, enum_value, safe_account, gating, GCS). Cap the list at MAX_MAP_ENTRIES (32). 32 distinct (chain, contract, selector, id, key) tuples is well above realistic per-transaction clear-signing needs while keeping the worst-case footprint around ~3.5 KB. This only addresses the DoS component of the finding. Replay protection (binding the descriptor to a per-session challenge in its signed TLV) requires a backend payload change and is left out of scope. Co-Authored-By: Claude Opus 4.7 --- src/features/provide_map_entry/map_entry.c | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/src/features/provide_map_entry/map_entry.c b/src/features/provide_map_entry/map_entry.c index 4891b387f..a6e5daea0 100644 --- a/src/features/provide_map_entry/map_entry.c +++ b/src/features/provide_map_entry/map_entry.c @@ -13,6 +13,11 @@ #define STRUCT_VERSION 0x01 +// Cap on accepted map entries to bound the shared app-memory pool. Map entries +// are scoped to one transaction (cleared by reset_app_context), so this only +// needs to cover the largest legitimate per-tx use, not aggregate session use. +#define MAX_MAP_ENTRIES 32 + static s_map_entry *g_map_entry_list = NULL; static bool handle_version(const tlv_data_t *data, s_map_entry_ctx *context) { @@ -137,6 +142,10 @@ bool verify_map_entry_struct(const s_map_entry_ctx *context) { PRINTF("Error: Signature verification failed for MAP_ENTRY descriptor!\n"); return false; } + if (flist_size((flist_node_t **) &g_map_entry_list) >= MAX_MAP_ENTRIES) { + PRINTF("Error: MAP_ENTRY list cap reached (%d)\n", MAX_MAP_ENTRIES); + return false; + } if ((entry = APP_MEM_ALLOC(sizeof(*entry))) == NULL) { PRINTF("Error: Not enough memory for MAP_ENTRY!\n"); return false; From 171278337b8e45d963218f31811a206941e5f171 Mon Sep 17 00:00:00 2001 From: Charles-Edouard de la Vergne Date: Tue, 12 May 2026 17:03:19 +0200 Subject: [PATCH 02/29] fix: ERC-20 plugin masks address-formatting error with RESULT_OK Add the missing break; after the error assignment so the success path is taken only when address formatting actually succeeds. --- src/plugins/erc20/erc20_plugin.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/plugins/erc20/erc20_plugin.c b/src/plugins/erc20/erc20_plugin.c index f23e08b78..763cddd9f 100644 --- a/src/plugins/erc20/erc20_plugin.c +++ b/src/plugins/erc20/erc20_plugin.c @@ -230,8 +230,9 @@ void erc20_plugin_call(eth_plugin_msg_t message, void *parameters) { msg->msgLength, g_chain_config->chain_id)) { msg->result = ETH_PLUGIN_RESULT_ERROR; + } else { + msg->result = ETH_PLUGIN_RESULT_OK; } - msg->result = ETH_PLUGIN_RESULT_OK; break; case 2: { PRINTF("Extra Data Length %d\n", context->extra_data_len); From 401aa94f300d9f1f45c601d57c04ace9ec85307f Mon Sep 17 00:00:00 2001 From: Charles-Edouard de la Vergne Date: Tue, 12 May 2026 18:21:14 +0200 Subject: [PATCH 03/29] fix: Replace ad-hoc GCC -Wformat suppression with bytes_to_lowercase_hex check_bytes_constraint() and format_bytes() in the generic TX parser rendered byte values as "0x" + hex via snprintf("0x%.*h", ...) and silenced GCC with a localized -Wformat suppression because the %h length-prefixed hex specifier is a BOLOS extension the compiler does not recognize. The pragma block silences any -Wformat issue inside its scope, hiding genuine format/argument mismatches that may arise from later edits in the same window. Prefix the destination buffer with "0x" and call bytes_to_lowercase_hex() to fill the rest, which preserves the lowercase casing the original %h specifier produced (and that the existing GCS snapshots match) without needing a diagnostic suppression. Co-Authored-By: Claude Opus 4.7 --- .../generic_tx_parser/gtp_param_raw.c | 45 ++++++++++++------- tests/unit/CMakeLists.txt | 11 ----- tests/unit/mocks/mock.c | 18 ++++++++ tests/unit/mocks/os.h | 7 +++ 4 files changed, 53 insertions(+), 28 deletions(-) diff --git a/src/features/generic_tx_parser/gtp_param_raw.c b/src/features/generic_tx_parser/gtp_param_raw.c index 266a4f054..9bf22ab70 100644 --- a/src/features/generic_tx_parser/gtp_param_raw.c +++ b/src/features/generic_tx_parser/gtp_param_raw.c @@ -1,3 +1,4 @@ +#include "os.h" #include "os_print.h" #include "common_utils.h" #include "gtp_param_raw.h" @@ -244,11 +245,17 @@ static bool check_bytes_constraint(const s_field *field, PRINTF("Warning: RAW BYTES constraint wrong size!\n"); continue; } - memset(constraint, 0, sizeof(constraint)); -#pragma GCC diagnostic push -#pragma GCC diagnostic ignored "-Wformat" - snprintf(constraint, sizeof(constraint), "0x%.*h", c_node->size, c_node->value); -#pragma GCC diagnostic pop + if (sizeof(constraint) < 3) { + continue; + } + constraint[0] = '0'; + constraint[1] = 'x'; + if (bytes_to_lowercase_hex(constraint + 2, + sizeof(constraint) - 2, + c_node->value, + c_node->size) != 0) { + continue; + } if (strcmp(formatted_buf, constraint) == 0) { return true; } @@ -263,10 +270,22 @@ static bool format_bytes(const s_field *field, size_t buf_size) { LEDGER_ASSERT(sizeof(strings.tmp.tmp) == buf_size, "Buffer too small for bytes formatting"); -#pragma GCC diagnostic push -#pragma GCC diagnostic ignored "-Wformat" - snprintf(buf, buf_size, "0x%.*h", value->length, value->ptr); -#pragma GCC diagnostic pop + // "0x" prefix + two hex digits per byte + NULL terminator. Reject upfront + // so the rejection is self-documenting rather than implied by + // bytes_to_lowercase_hex's internal size check, and the caller gets a + // clean ERROR APDU instead of a silently truncated review screen. + const size_t needed = (size_t) 2 + (size_t) value->length * 2 + 1; + if (needed > buf_size) { + PRINTF("RAW BYTES value too long for display (%u > %u bytes)\n", + (unsigned) needed, + (unsigned) buf_size); + return false; + } + buf[0] = '0'; + buf[1] = 'x'; + if (bytes_to_lowercase_hex(buf + 2, buf_size - 2, value->ptr, value->length) != 0) { + return false; + } if (!apply_visibility_constraint(field, to_be_displayed, @@ -274,14 +293,6 @@ static bool format_bytes(const s_field *field, return false; } - if (!*to_be_displayed) { - return true; - } - - // Truncate if needed for display - if ((2 + (value->length * 2) + 1) > (int) buf_size) { - memmove(&buf[buf_size - 1 - 3], "...", 3); - } return true; } diff --git a/tests/unit/CMakeLists.txt b/tests/unit/CMakeLists.txt index 2411ff779..32ee8720c 100644 --- a/tests/unit/CMakeLists.txt +++ b/tests/unit/CMakeLists.txt @@ -209,12 +209,6 @@ add_executable(test_param_raw ${BOLOS_SDK}/lib_tlv/tlv_library.c ) -# Disable -Wformat warnings for gtp_param_raw.c (uses BOLOS_SDK specific %.*h format) -set_source_files_properties( - ${APP_DIR}/features/generic_tx_parser/gtp_param_raw.c - PROPERTIES COMPILE_FLAGS "-Wno-format -Wno-format-extra-args" -) - target_compile_definitions(test_param_raw PRIVATE HAVE_ECDSA HAVE_HASH @@ -259,11 +253,6 @@ add_executable(test_field_validation # Disable pedantic warnings for SDK's tlv_library.c set_source_files_properties(${BOLOS_SDK}/lib_tlv/tlv_library.c PROPERTIES COMPILE_FLAGS "-Wno-pedantic") -# Disable -Wformat warnings for gtp_param_raw.c (uses BOLOS_SDK specific %.*h format) -set_source_files_properties( - ${APP_DIR}/features/generic_tx_parser/gtp_param_raw.c - PROPERTIES COMPILE_FLAGS "-Wno-format -Wno-format-extra-args" -) target_compile_definitions(test_field_validation PRIVATE HAVE_ECDSA HAVE_HASH diff --git a/tests/unit/mocks/mock.c b/tests/unit/mocks/mock.c index 247043ff1..fd8ee41b5 100644 --- a/tests/unit/mocks/mock.c +++ b/tests/unit/mocks/mock.c @@ -12,6 +12,24 @@ void *pic(void *addr) { return addr; } +// Mirror of BOLOS_SDK os.c implementation; pulled in here so unit tests don't +// have to link the whole os.c (which drags in BSS/syscall machinery). +int bytes_to_lowercase_hex(char *out, size_t outl, const void *value, size_t len) { + const uint8_t *bytes = (const uint8_t *) value; + const char *hex = "0123456789abcdef"; + + if (outl < 2 * len + 1) { + *out = '\0'; + return -1; + } + for (size_t i = 0; i < len; i++) { + *out++ = hex[(bytes[i] >> 4) & 0xf]; + *out++ = hex[bytes[i] & 0xf]; + } + *out = '\0'; + return 0; +} + bool is_printable_string(const char *str, size_t len) { for (size_t i = 0; i < len; ++i) { if (str[i] < 0x20 || str[i] > 0x7E) { diff --git a/tests/unit/mocks/os.h b/tests/unit/mocks/os.h index 769de8803..a7013908a 100644 --- a/tests/unit/mocks/os.h +++ b/tests/unit/mocks/os.h @@ -1,8 +1,15 @@ #pragma once +#include #include // strlcpy, strlcat from libbsd /** * @brief Array length macro (from BOLOS_SDK os_utils.h) */ #define ARRAYLEN(array) (sizeof(array) / sizeof(array[0])) + +/** + * @brief Hex-encode bytes as a lowercase null-terminated string. + * Mirrors BOLOS_SDK os_utils.h declaration; impl lives in mock.c. + */ +int bytes_to_lowercase_hex(char *out, size_t outl, const void *value, size_t len); From 6b39cf1606a364cee42231175be5e68cd88cbc2b Mon Sep 17 00:00:00 2001 From: Charles-Edouard de la Vergne Date: Wed, 13 May 2026 11:56:15 +0200 Subject: [PATCH 04/29] test: Cover GCS raw-bytes display oversize rejection format_bytes() in the generic TX parser refuses an oversize raw-bytes field at field-description time rather than rendering it truncated. That behavior protects the user from a hash/display mismatch on the review screen, but it was previously exercised only implicitly: the existing GCS tests use small payloads, so any regression that silently re-introduced truncation would not show up in CI. Add test_gcs_raw_bytes_oversize_rejected, which injects a 200-byte payload into the `signature` parameter of the existing PoAP `mintToken` ABI and exposes it through a PARAM_TYPE_RAW / TypeFamily.BYTES field. With "0x" + 400 hex digits + NUL = 403 chars needed against the 380-byte strings.tmp.tmp buffer, the device must return SWO_INCORRECT_DATA on the field-descriptor APDU. Asserts that status word via pytest.raises(ExceptionRAPDU). Co-Authored-By: Claude Opus 4.7 --- tests/ragger/test_gcs_formatters.py | 77 +++++++++++++++++++++++++++++ 1 file changed, 77 insertions(+) diff --git a/tests/ragger/test_gcs_formatters.py b/tests/ragger/test_gcs_formatters.py index fdfec812b..8522747f6 100644 --- a/tests/ragger/test_gcs_formatters.py +++ b/tests/ragger/test_gcs_formatters.py @@ -1107,3 +1107,80 @@ def test_gcs_iteration_broadcast(scenario_navigator: NavigateWithScenario): with app_client.sign(mode=SignMode.START_FLOW): scenario_navigator.review_approve() + + +def test_gcs_raw_bytes_oversize_rejected(scenario_navigator: NavigateWithScenario): + """A PARAM_TYPE_RAW + TypeFamily.BYTES field whose value exceeds the + on-device hex-display buffer (~188 bytes of raw payload) must be refused + at field-description time instead of rendered truncated. Without that + rejection the user would sign a hash computed over the full payload while + only a prefix is shown.""" + app_client = EthAppClient(scenario_navigator.backend) + + # mintToken accepts a free-form `bytes signature` parameter; we abuse it + # as the oversize bytes carrier. 200 raw bytes => "0x" + 400 hex chars + + # NUL = 403 chars, well above the 380-byte display buffer. + oversize_signature = bytes(range(200)) + + with open(f"{ABIS_FOLDER}/poap.abi.json", encoding="utf-8") as file: + contract = Web3().eth.contract(abi=json.load(file), address=None) + data = contract.encode_abi("mintToken", [ + 175676, + 7163978, + bytes.fromhex("Dad77910DbDFdE764fC21FCD4E74D71bBACA6D8D"), + 1730621615, + oversize_signature, + ]) + tx_params = { + "nonce": 235, + "maxFeePerGas": Web3.to_wei(100, "gwei"), + "maxPriorityFeePerGas": Web3.to_wei(10, "gwei"), + "gas": 44001, + "to": bytes.fromhex("0bb4D3e88243F4A057Db77341e6916B0e449b158"), + "data": data, + "chainId": 1, + } + + with app_client.sign("m/44'/60'/0'/0/0", tx_params, mode=SignMode.STORE): + pass + + param_paths = get_all_paths(f"{ABIS_FOLDER}/poap.abi.json", "mintToken") + fields = [ + Field( + 1, + "Signature", + ParamRaw( + 1, + Value( + 1, + TypeFamily.BYTES, + data_path=DataPath(1, param_paths["signature"]), + ), + ), + ), + ] + + inst_hash = compute_inst_hash(fields) + tx_info = TxInfo( + 1, + tx_params["chainId"], + tx_params["to"], + get_selector_from_data(tx_params["data"]), + inst_hash, + "mint POAP", + creator_name="POAP", + creator_legal_name="Proof of Attendance Protocol", + creator_url="poap.xyz", + contract_name="PoapBridge", + deploy_date=1646305200, + ) + + app_client.provide_transaction_info(tx_info.serialize()) + + # The single oversize Field must be rejected when its description APDU + # reaches format_field() -> format_bytes(), which now returns false + # rather than truncating the hex string. + with pytest.raises(ExceptionRAPDU) as err: + for field in fields: + app_client.provide_transaction_field_desc(field.serialize()) + assert err.value.status == StatusWord.SWO_INCORRECT_DATA From db3dcc2800ef66b21467c8a6ad1d92540ded1620 Mon Sep 17 00:00:00 2001 From: Charles-Edouard de la Vergne Date: Tue, 12 May 2026 18:22:13 +0200 Subject: [PATCH 05/29] fix: Avoid unaligned uint16_t load in EIP-712 field_hash_prepare field_hash_prepare() read the 2-byte declared-size prefix of an EIP-712 dynamic field with `*(uint16_t *) &data[0]`. data points into the APDU buffer and is not guaranteed to be 2-byte aligned, which is undefined behavior on strict-alignment ARM targets and risks a bus fault depending on incoming chunk boundaries. Use the SDK's read_u16_be() helper, which does a byte-by-byte big- endian decode and works regardless of alignment, removing both the UB and the __builtin_bswap16() that was paired with it. Co-Authored-By: Claude Opus 4.7 --- src/features/sign_message_eip712/field_hash.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/features/sign_message_eip712/field_hash.c b/src/features/sign_message_eip712/field_hash.c index 18a318ec8..fdb69b6e4 100644 --- a/src/features/sign_message_eip712/field_hash.c +++ b/src/features/sign_message_eip712/field_hash.c @@ -11,6 +11,7 @@ #include "typed_data.h" #include "commands_712.h" #include "hash_bytes.h" +#include "read.h" static s_field_hashing *fh = NULL; @@ -51,7 +52,7 @@ void field_hash_deinit(void) { static const uint8_t *field_hash_prepare(const s_struct_712_field *field_ptr, const uint8_t *data, uint8_t *data_length) { - fh->remaining_size = __builtin_bswap16(*(uint16_t *) &data[0]); // network byte order + fh->remaining_size = read_u16_be(data, 0); data += sizeof(uint16_t); *data_length -= sizeof(uint16_t); fh->state = FHS_WAITING_FOR_MORE; From 04504cfde06401a9cc675f966085715a0c8add57 Mon Sep 17 00:00:00 2001 From: Charles-Edouard de la Vergne Date: Tue, 12 May 2026 18:22:48 +0200 Subject: [PATCH 06/29] fix: Return NULL on enum-value snprintf failure in GCS extra-data handler MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit handle_extra_data_enum() returns a `const nbgl_contentValueExt_t *` but the failure path of its snprintf() guard returned `false`. C lets the implicit bool→pointer conversion compile (0 → NULL), so the behavior was accidentally correct, but the literal is misleading and masks the intent of the early-return. Return NULL explicitly to match the pointer return type. Co-Authored-By: Claude Opus 4.7 --- src/nbgl/ui_gcs.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/nbgl/ui_gcs.c b/src/nbgl/ui_gcs.c index 196d0ffc5..019f4c0ca 100644 --- a/src/nbgl/ui_gcs.c +++ b/src/nbgl/ui_gcs.c @@ -360,7 +360,7 @@ static const nbgl_contentValueExt_t *handle_extra_data_enum(const s_field_table_ const char *values[] = {formatted_value}; if (snprintf(formatted_value, sizeof(formatted_value), "%u", enum_value->value) <= 0) { - return false; + return NULL; } return get_infolist_extension(enum_value->name, ARRAYLEN(keys), keys, values); } From dba1814ffd5e0bf87f33affe30a5ded151cece38 Mon Sep 17 00:00:00 2001 From: Charles-Edouard de la Vergne Date: Tue, 12 May 2026 18:23:37 +0200 Subject: [PATCH 07/29] fix: Reject ERC-1155 batch transfers whose aggregate quantity overflows The ERC-1155 batch_transfer parser accumulates per-id values into context->value via add256() to compute the total quantity displayed on the review screen. add256 wraps on uint256 overflow without signalling, so a crafted calldata whose values sum past 2^256 would silently produce a truncated total - a hostile dApp could pair a benign-looking aggregate with adversarial per-id quantities. After each accumulation, detect overflow by checking gt256(&new_value, &context->value): when the running total is now smaller than the addend, the sum has wrapped. Set the plugin result to ERROR so the host cannot present a misleading review screen. Co-Authored-By: Claude Opus 4.7 --- src/plugins/erc1155/erc1155_provide_parameters.c | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/src/plugins/erc1155/erc1155_provide_parameters.c b/src/plugins/erc1155/erc1155_provide_parameters.c index d5f6aab43..f2e3583a9 100644 --- a/src/plugins/erc1155/erc1155_provide_parameters.c +++ b/src/plugins/erc1155/erc1155_provide_parameters.c @@ -114,6 +114,15 @@ static void handle_batch_transfer(ethPluginProvideParameter_t *msg, erc1155_cont } convertUint256BE(context->tokenId, sizeof(context->tokenId), &new_value); add256(&context->value, &new_value, &context->value); + // Reject crafted batches whose per-id totals wrap uint256. With + // the partial sum already stored in context->value, an overflow + // would silently misreport the aggregate "total quantity" shown + // to the user. + if (gt256(&new_value, &context->value)) { + PRINTF("Batch transfer aggregate quantity overflow\n"); + msg->result = ETH_PLUGIN_RESULT_ERROR; + break; + } if (--context->values_array_len == 0) { context->next_param = NONE; } From f8ddbbe29799368ea3339333debcdcef80692cd7 Mon Sep 17 00:00:00 2001 From: Charles-Edouard de la Vergne Date: Tue, 12 May 2026 18:24:48 +0200 Subject: [PATCH 08/29] fix: Avoid signed-int UB when decoding 4-byte RLP length headers rlp_decode_length() decoded RLP_*_LEN_OF_BYTES_4 strings and lists with `*(buffer + 1) << 24` where buffer is a uint8_t pointer. The C integer promotions widen the byte to a signed `int`, and a shift by 24 of an `int` whose result sets the sign bit is undefined behavior under the standard. In practice this triggers whenever the most- significant byte of the encoded length is >= 0x80. Cast each byte to uint32_t before shifting (and switch from `+` to `|` so the byte composition matches the surrounding intent), removing the UB without changing the decoded value. Co-Authored-By: Claude Opus 4.7 --- src/features/sign_tx/rlp_utils.c | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/src/features/sign_tx/rlp_utils.c b/src/features/sign_tx/rlp_utils.c index c43503994..30fce996a 100644 --- a/src/features/sign_tx/rlp_utils.c +++ b/src/features/sign_tx/rlp_utils.c @@ -77,8 +77,9 @@ bool rlp_decode_length(uint8_t *buffer, uint32_t *fieldLength, uint32_t *offset, *fieldLength = (*(buffer + 1) << 16) + (*(buffer + 2) << 8) + *(buffer + 3); break; case RLP_STR_LEN_OF_BYTES_4: - *fieldLength = (*(buffer + 1) << 24) + (*(buffer + 2) << 16) + - (*(buffer + 3) << 8) + *(buffer + 4); + *fieldLength = ((uint32_t) * (buffer + 1) << 24) | + ((uint32_t) * (buffer + 2) << 16) | + ((uint32_t) * (buffer + 3) << 8) | *(buffer + 4); break; default: return false; // arbitrary 32 bits length limitation @@ -101,8 +102,9 @@ bool rlp_decode_length(uint8_t *buffer, uint32_t *fieldLength, uint32_t *offset, *fieldLength = (*(buffer + 1) << 16) + (*(buffer + 2) << 8) + *(buffer + 3); break; case RLP_LIST_LEN_OF_BYTES_4: - *fieldLength = (*(buffer + 1) << 24) + (*(buffer + 2) << 16) + - (*(buffer + 3) << 8) + *(buffer + 4); + *fieldLength = ((uint32_t) * (buffer + 1) << 24) | + ((uint32_t) * (buffer + 2) << 16) | + ((uint32_t) * (buffer + 3) << 8) | *(buffer + 4); break; default: return false; // arbitrary 32 bits length limitation From e0bcad90eddae1c4eb0a93301caeb4a1c4e9bccd Mon Sep 17 00:00:00 2001 From: Charles-Edouard de la Vergne Date: Tue, 12 May 2026 18:26:05 +0200 Subject: [PATCH 09/29] fix: Honor CALLDATA_FLAG_ADDR_FILTER for the EIP-712 calldata spender The signed calldata-info filter payload allows the spender to be provided dynamically (CALLDATA_FLAG_ADDR_FILTER), the same way the callee already supports. The accept-path switch on spender_flag handled CALLDATA_FLAG_ADDR_VERIFYING_CONTRACT and CALLDATA_FLAG_ADDR_NONE explicitly but fell into the default branch for CALLDATA_FLAG_ADDR_FILTER, leaving calldata_info->spender_state at its calloc-zero value (CALLDATA_INFO_PARAM_NONE). The downstream filter-ingestion check requires spender_state == PARAM_UNSET, so a matching filter would be rejected and the spender screen never populated. Add the missing case: set spender_state to PARAM_UNSET to mirror the callee_flag handling so a follow-up filter can populate the value. Co-Authored-By: Claude Opus 4.7 --- src/features/sign_message_eip712/filtering.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/features/sign_message_eip712/filtering.c b/src/features/sign_message_eip712/filtering.c index 52bbf4138..e9a84b430 100644 --- a/src/features/sign_message_eip712/filtering.c +++ b/src/features/sign_message_eip712/filtering.c @@ -814,6 +814,9 @@ bool filtering_calldata_info(const uint8_t *payload, uint8_t length) { get_public_key(calldata_info->spender, sizeof(calldata_info->spender)); calldata_info->spender_state = CALLDATA_INFO_PARAM_SET; break; + case CALLDATA_FLAG_ADDR_FILTER: + calldata_info->spender_state = CALLDATA_INFO_PARAM_UNSET; + break; default: break; } From 4cdcc60fecd7ac7bd0068a1cf2e73f58f6629669 Mon Sep 17 00:00:00 2001 From: Charles-Edouard de la Vergne Date: Tue, 12 May 2026 18:26:56 +0200 Subject: [PATCH 10/29] fix: Re-anchor gated-signing counter on uint8 wrap to keep cadence aligned The gated-signing screen is meant to render every GATED_SIGNING_MAX_COUNT (10) signing operations, gated by a uint8_t counter in N_storage. Because 256 is not a multiple of 10, the natural uint8_t wrap shifts the cadence: a display would land on sign #251, then nothing until sign #257 (gap of 6 instead of 10), then the cycle is permanently out of phase relative to its starting point. Detect the wrap (`counter + 1 == 0` after `uint8_t` promotion) and re-anchor the stored counter to 1, which forces a display on the wrap-spanning signing operation and resumes the every-10th cadence from a known phase. The wrap-adjacent interval is 5 signs instead of 10, accepted as a one-time anomaly; every subsequent cycle is exactly 10. Note: the modulo expression itself (`counter % MAX == 1`) is equivalent to the original `(counter - 1) % MAX == 0` for every uint8_t value, because C integer promotions make `counter - 1` signed (`-1 % 10 == -1`, not 255). The previous form was readable and correct; the fix above addresses the genuine wrap-cadence drift the previous form did not cover. Co-Authored-By: Claude Opus 4.7 --- src/features/provide_gating/cmd_get_gating.c | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/src/features/provide_gating/cmd_get_gating.c b/src/features/provide_gating/cmd_get_gating.c index 7431da4fc..804821c8f 100644 --- a/src/features/provide_gating/cmd_get_gating.c +++ b/src/features/provide_gating/cmd_get_gating.c @@ -665,11 +665,19 @@ bool set_gating_warning(void) { return false; } - // Check the counter + // Bump the persistent counter. The uint8_t wraps every 256 signing + // operations; 256 is not a multiple of GATED_SIGNING_MAX_COUNT, so a + // naive `counter + 1` would shift the "display every Nth" cadence after + // each wrap and eventually skip a screen entirely. Detect the wrap and + // re-anchor to 1 so the next signing operation displays and the cycle + // resumes aligned. counter = N_storage.gating_counter + 1; + if (counter == 0) { + counter = 1; + } PRINTF("[GATING] Counter: %d/%d\n", counter, GATED_SIGNING_MAX_COUNT); nvm_write((void *) &N_storage.gating_counter, (void *) &counter, sizeof(counter)); - if (((counter - 1) % GATED_SIGNING_MAX_COUNT) != 0) { + if ((counter % GATED_SIGNING_MAX_COUNT) != 1) { PRINTF("[GATING] Skip gating screen\n"); return true; } From 0577113d9768bfb76e232173d43b721f90b768df Mon Sep 17 00:00:00 2001 From: Charles-Edouard de la Vergne Date: Tue, 12 May 2026 19:16:06 +0200 Subject: [PATCH 11/29] fix: Drop misleading `const` on TLV-populated descriptor fields safe_descriptor_t::address and four gating_t fields (hash_selector, intro_msg, tiny_url, address) were declared `const` to document that they should not change after parsing, but the TLV handlers wrote into them through `(uint8_t *)` / `(char *)` casts that strip the qualifier. The underlying storage comes from APP_MEM_CALLOC() so this is not strict undefined behaviour, but it is a pattern several static analyzers flag and it weakens the type signal at every read site. Remove the `const` from the five fields and drop the corresponding casts at the parser call sites where they were stripping the qualifier. The two remaining `(uint8_t *)` casts on `char` fields stay since they still perform a char->uint8_t conversion required by the TLV helper signatures. Co-Authored-By: Claude Opus 4.7 --- src/features/provide_gating/cmd_get_gating.c | 16 ++++++++-------- .../provide_safe_account/safe_descriptor.h | 2 +- 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/src/features/provide_gating/cmd_get_gating.c b/src/features/provide_gating/cmd_get_gating.c index 804821c8f..295c55e2c 100644 --- a/src/features/provide_gating/cmd_get_gating.c +++ b/src/features/provide_gating/cmd_get_gating.c @@ -60,10 +60,10 @@ typedef enum { typedef struct gating_s { uint64_t chain_id; - const uint8_t hash_selector[CX_SHA224_SIZE]; // function selector for SignTx or schemaHash for EIP712 - const char intro_msg[GATING_MSG_SIZE + 1]; // +1 for the null terminator - const char tiny_url[GATING_URL_SIZE + 1]; // +1 for the null terminator - const uint8_t address[ADDRESS_LENGTH]; // Contract address to check in the gating + uint8_t hash_selector[CX_SHA224_SIZE]; // function selector for SignTx or schemaHash for EIP712 + char intro_msg[GATING_MSG_SIZE + 1]; // +1 for the null terminator + char tiny_url[GATING_URL_SIZE + 1]; // +1 for the null terminator + uint8_t address[ADDRESS_LENGTH]; // Contract address to check in the gating tx_type_t type; } gating_t; @@ -129,7 +129,7 @@ static bool parse_hash_selector(const tlv_data_t *data, s_gating_ctx *context) { PRINTF("HASH/SELECTOR: invalid size\n"); return false; } - return tlv_get_hash(data, (uint8_t *) context->gating->hash_selector, data->value.size); + return tlv_get_hash(data, context->gating->hash_selector, data->value.size); } /** @@ -140,7 +140,7 @@ static bool parse_hash_selector(const tlv_data_t *data, s_gating_ctx *context) { * @return whether it was successful */ static bool parse_address(const tlv_data_t *data, s_gating_ctx *context) { - if (!tlv_get_address(data, (uint8_t *) context->gating->address)) { + if (!tlv_get_address(data, context->gating->address)) { return false; } if (is_zeroes_buffer(context->gating->address, ADDRESS_LENGTH)) { @@ -170,7 +170,7 @@ static bool parse_chain_id(const tlv_data_t *data, s_gating_ctx *context) { */ static bool parse_intro_msg(const tlv_data_t *data, s_gating_ctx *context) { if (!tlv_get_printable_string(data, - (char *) context->gating->intro_msg, + context->gating->intro_msg, 0, sizeof(context->gating->intro_msg))) { PRINTF("INTRO_MSG: error\n"); @@ -188,7 +188,7 @@ static bool parse_intro_msg(const tlv_data_t *data, s_gating_ctx *context) { */ static bool parse_tiny_url(const tlv_data_t *data, s_gating_ctx *context) { if (!tlv_get_printable_string(data, - (char *) context->gating->tiny_url, + context->gating->tiny_url, 0, sizeof(context->gating->tiny_url))) { PRINTF("TINY_URL: error\n"); diff --git a/src/features/provide_safe_account/safe_descriptor.h b/src/features/provide_safe_account/safe_descriptor.h index 1d085d4c0..010287af6 100644 --- a/src/features/provide_safe_account/safe_descriptor.h +++ b/src/features/provide_safe_account/safe_descriptor.h @@ -17,7 +17,7 @@ typedef enum { "Unknown") typedef struct { - const char address[ADDRESS_LENGTH]; + char address[ADDRESS_LENGTH]; uint16_t threshold; uint16_t signers_count; safe_role_t role; From a74c1a948c7c84be4c88f373e4b249600ddf9162 Mon Sep 17 00:00:00 2001 From: Charles-Edouard de la Vergne Date: Tue, 12 May 2026 19:21:05 +0200 Subject: [PATCH 12/29] fix: Release EIP-712 type dependency list on every type_hash exit path type_hash() allocated a sorted dependency list via get_struct_dependencies() to enumerate the structs that need to be hashed alongside the root type. The list was only freed at the very end of the happy path: any early return after the allocation - including a partial population on get_struct_dependencies() failure - skipped the flist_clear() and leaked nodes into the shared app-memory pool for the rest of the session. Restructure with a single `end:` label that runs flist_clear() unconditionally. The two pre-allocation early returns (missing struct lookup, keccak init failure) keep their direct returns since no list exists yet. Co-Authored-By: Claude Opus 4.7 --- src/features/sign_message_eip712/type_hash.c | 20 ++++++++++++-------- 1 file changed, 12 insertions(+), 8 deletions(-) diff --git a/src/features/sign_message_eip712/type_hash.c b/src/features/sign_message_eip712/type_hash.c index db496e18c..a6e7f0778 100644 --- a/src/features/sign_message_eip712/type_hash.c +++ b/src/features/sign_message_eip712/type_hash.c @@ -179,7 +179,8 @@ static void delete_struct_dep(s_struct_dep *sdep) { */ bool type_hash(const char *struct_name, const uint8_t struct_name_length, uint8_t *hash_buf) { const void *struct_ptr; - s_struct_dep *deps; + s_struct_dep *deps = NULL; + bool ret = false; if ((struct_ptr = get_structn(struct_name, struct_name_length)) == NULL) { PRINTF("Error: could not find EIP-712 struct \""); @@ -190,26 +191,29 @@ bool type_hash(const char *struct_name, const uint8_t struct_name_length, uint8_ if (cx_keccak_init_no_throw(&global_sha3, 256) != CX_OK) { return false; } - deps = NULL; + // get_struct_dependencies may populate `deps` partially before failing; + // every exit path past this point must release the list. if (!get_struct_dependencies(&deps, struct_ptr)) { - return false; + goto end; } flist_sort((flist_node_t **) &deps, (f_list_node_cmp) &compare_struct_deps); if (encode_and_hash_type(struct_ptr) == false) { - return false; + goto end; } // loop over each struct and generate string for (const s_struct_dep *tmp = deps; tmp != NULL; tmp = (s_struct_dep *) ((flist_node_t *) tmp)->next) { if (encode_and_hash_type(tmp->s) == false) { - return false; + goto end; } } - flist_clear((flist_node_t **) &deps, (f_list_node_del) &delete_struct_dep); // copy hash into memory if (finalize_hash((cx_hash_t *) &global_sha3, hash_buf, KECCAK256_HASH_BYTESIZE) != true) { - return false; + goto end; } - return true; + ret = true; +end: + flist_clear((flist_node_t **) &deps, (f_list_node_del) &delete_struct_dep); + return ret; } From 096cddffb30a5b0d68ba66e7b2949f449d8a4620 Mon Sep 17 00:00:00 2001 From: Charles-Edouard de la Vergne Date: Tue, 12 May 2026 19:21:25 +0200 Subject: [PATCH 13/29] fix: Free home-screen plugin tagline before reallocating get_appname_and_tagline() allocates g_tag_line on every home-screen transition where the caller is a plugin, but nothing freed the prior buffer first ? the comment at the allocation point even acknowledged "will never be deallocated". Each return to the home screen during a plugin-driven session (post-tx, post-cancel, multi-flow plugins) therefore leaked roughly the plugin name length plus the tagline template into the shared app-memory pool, slowly starving the rest of the session. Release the previous allocation with APP_MEM_FREE_AND_NULL() before the next APP_MEM_CALLOC() so the pool only ever holds one live tagline buffer. Co-Authored-By: Claude Opus 4.7 --- src/nbgl/ui_home.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/src/nbgl/ui_home.c b/src/nbgl/ui_home.c index 50ad5b472..19cd29081 100644 --- a/src/nbgl/ui_home.c +++ b/src/nbgl/ui_home.c @@ -237,7 +237,13 @@ static void get_appname_and_tagline(const char **appname, const char **tagline) return; } size_t line_len = 1 + strlen(FORMAT_PLUGIN) + name_len; - // Allocate the buffer - will never be deallocated... + // Free any tagline left over from a previous home transition + // before allocating a new one; without this, repeated returns + // to the home screen in the same session accumulate orphaned + // buffers in the app-memory pool. + if (g_tag_line != NULL) { + APP_MEM_FREE_AND_NULL((void **) &g_tag_line); + } if (APP_MEM_CALLOC((void **) &g_tag_line, line_len) == true) { snprintf(g_tag_line, line_len, FORMAT_PLUGIN, *appname); *tagline = g_tag_line; From 37edafc1124696618746cd22b596485b35c46f75 Mon Sep 17 00:00:00 2001 From: Charles-Edouard de la Vergne Date: Tue, 12 May 2026 19:21:46 +0200 Subject: [PATCH 14/29] fix: Render full 48-byte ETH2 deposit BLS pubkey on validator screen The ETH2 deposit plugin reassembled the 48-byte BLS12-381 G1 compressed pubkey from two parameter chunks, then passed the raw buffer to getEthDisplayableAddress() to produce the screen string. That helper is hard-coded for 20-byte Ethereum addresses: its inner getEthAddressStringFromBinary() loops `for (i = 0; i < 20; i++)` and silently ignores the trailing 28 bytes of the pubkey. The validator "deposit address" shown to the user was therefore only the first 20 bytes of the 48-byte pubkey, hex-encoded, leaving the user unable to verify they were approving the intended validator. Keep the pubkey stored as raw 48 bytes and render it on screen as "0x" + bytes_to_lowercase_hex() inside the QUERY_CONTRACT_UI handler. Lowercase matches the casing the original getEthDisplayableAddress path produced for the truncated display. Co-Authored-By: Claude Opus 4.7 --- src/plugins/eth2/eth2_plugin.c | 31 +++++++++--------- .../apex_p/test_eth2_deposit/00001.png | Bin 5829 -> 4084 bytes .../apex_p/test_eth2_deposit/00002.png | Bin 2841 -> 6603 bytes .../flex/test_eth2_deposit/00001.png | Bin 22873 -> 14682 bytes .../flex/test_eth2_deposit/00002.png | Bin 8804 -> 25373 bytes .../nanosp/test_eth2_deposit/00003.png | Bin 745 -> 944 bytes .../nanosp/test_eth2_deposit/00004.png | Bin 536 -> 817 bytes .../nanosp/test_eth2_deposit/00005.png | Bin 438 -> 536 bytes .../nanosp/test_eth2_deposit/00006.png | Bin 298 -> 438 bytes .../nanosp/test_eth2_deposit/00007.png | Bin 0 -> 298 bytes .../nanox/test_eth2_deposit/00003.png | Bin 745 -> 944 bytes .../nanox/test_eth2_deposit/00004.png | Bin 536 -> 817 bytes .../nanox/test_eth2_deposit/00005.png | Bin 438 -> 536 bytes .../nanox/test_eth2_deposit/00006.png | Bin 298 -> 438 bytes .../nanox/test_eth2_deposit/00007.png | Bin 0 -> 298 bytes .../stax/test_eth2_deposit/00001.png | Bin 20472 -> 13305 bytes .../stax/test_eth2_deposit/00002.png | Bin 8277 -> 23293 bytes 17 files changed, 16 insertions(+), 15 deletions(-) create mode 100644 tests/ragger/snapshots/nanosp/test_eth2_deposit/00007.png create mode 100644 tests/ragger/snapshots/nanox/test_eth2_deposit/00007.png diff --git a/src/plugins/eth2/eth2_plugin.c b/src/plugins/eth2/eth2_plugin.c index 87db4334f..ea4d4aa76 100644 --- a/src/plugins/eth2/eth2_plugin.c +++ b/src/plugins/eth2/eth2_plugin.c @@ -105,23 +105,12 @@ void eth2_plugin_call(eth_plugin_msg_t message, void *parameters) { } case 4 + (PARAMETER_LENGTH * 6): // deposit pubkey 2 { - // Copy the last 16 bytes. + // Copy the last 16 bytes. Storage stays raw (48-byte BLS + // G1 compressed pubkey); the screen renders the full + // value as hex in the QUERY_CONTRACT_UI handler. memcpy(context->deposit_address + PARAMETER_LENGTH, msg->parameter, sizeof(context->deposit_address) - PARAMETER_LENGTH); - - // Use a temporary buffer to store the string representation. - char tmp[BLS12381_G1_COMPRESSED_PUBKEY_LENGTH]; - if (!getEthDisplayableAddress((uint8_t *) context->deposit_address, - tmp, - sizeof(tmp), - g_chain_config->chain_id)) { - msg->result = ETH_PLUGIN_RESULT_ERROR; - return; - } - - // Copy back the string to the global variable. - strlcpy(context->deposit_address, tmp, BLS12381_G1_COMPRESSED_PUBKEY_LENGTH); msg->result = ETH_PLUGIN_RESULT_OK; break; } @@ -212,7 +201,19 @@ void eth2_plugin_call(eth_plugin_msg_t message, void *parameters) { } break; case 1: { // Deposit pubkey screen strlcpy(msg->title, "Validator", msg->titleLength); - strlcpy(msg->msg, context->deposit_address, msg->msgLength); + if (msg->msgLength < 3) { + msg->result = ETH_PLUGIN_RESULT_ERROR; + break; + } + msg->msg[0] = '0'; + msg->msg[1] = 'x'; + if (bytes_to_lowercase_hex(&msg->msg[2], + msg->msgLength - 2, + context->deposit_address, + sizeof(context->deposit_address)) != 0) { + msg->result = ETH_PLUGIN_RESULT_ERROR; + break; + } msg->result = ETH_PLUGIN_RESULT_OK; } break; default: diff --git a/tests/ragger/snapshots/apex_p/test_eth2_deposit/00001.png b/tests/ragger/snapshots/apex_p/test_eth2_deposit/00001.png index 95c3dfc5435abb552f1fcb986e8f4b995bc0e847..8e63062805d77edaa357ce38df5950087bc77d84 100644 GIT binary patch literal 4084 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 diff --git a/tests/ragger/snapshots/apex_p/test_eth2_deposit/00002.png b/tests/ragger/snapshots/apex_p/test_eth2_deposit/00002.png index 4081c9ea501e9cb1a9ffd8a51600428399c97721..2c66661fa291b656067b666ce6ff098e0e04f0dc 100644 GIT binary patch literal 6603 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 S@K2KlpsQ)9QS;!@^Zx+I>uPlX literal 2841 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 U6Y~-9%p^!p%kX~H-KQ`A8y~(;-T(jq literal 22873 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 delta 722 zcmV;@0xkWp2k8ZnBYy(0Nkl0~S*7vqKW{NGdS z2og|6F=w_7000000L4LliAAe3%a%XaIKeX+JOKqRVr%&65 z^6PeZe<6s$O8&SVF_?_taKvC5aCIV#YN)5?SCev9BK3CVZBEi+8m6fAsA||Bn6hmwZhq|Gcv_=}OD{v&W!(0U=}29HUE4z-{WNA@m-MzQo{ zs@*E*e}5v|tNJpe9DUQK+OzSp2XAz0)=}zRo(vqCj{O5Ls4zF7Fd0R>goqkx+=wOF zu_p9Br_IPd+t4yUDqF^AduU^N^)wCRO1P@pGlt$V5KRIA00000o9EronRs@+p8cQL zg1w+ksQBvnNNGtzqTh-bO@@*!CtU!XZce{8000000Kf!(0CL6}EtUzwCIA2c07*qoM6N<$ Eg4B&#R{#J2 diff --git a/tests/ragger/snapshots/nanosp/test_eth2_deposit/00004.png b/tests/ragger/snapshots/nanosp/test_eth2_deposit/00004.png index 45411331a9b48053c0ae05f9667ad74dd52f4280..d7b41fb610f7f70321dad15084e6cfa15b39f69d 100644 GIT binary patch delta 795 zcmV+$1LXXe1hEE?BYy(;Nkln7FMnk349IU1Fl5Zm(iW}^ zX1YH}{dnMjEkal}175?e8i}}zt(;)ksuUR{u9k&2h5zjNt z!<+EMbQkM_6Q=aKhg7tLl>w+G{fz5gJL!IS*xcE;dlj1FfEZi8KY5U3iO+}n!IrcY^3iY}$IfxmH^mP_#> zh~_%#d4C^s)*uq2lQN{XA|6KMQqWb$NXr4g2{UTwZA+NeR$DW&h~GlDn7+_;jeriA zKmn+xc1s4Cn1E*cFFRUWZK<1covRDZ-SZ;~&Bp%+n389)e!4ug&J5KaED{uMk*fOv z0P6-7{CFPo_no@SZlmP@I0E+mLq@WxYg*ImHh+Q+3=b>2-p6vpX_j))?A4yXK2SX16qi61tE?~@{iFrRwx z-bbE;4&l%Mq}aOAeU&?ha|2*1^$)6^n>aTB6_2Z)n>hCv>a5z}G4%WmfDl3mA>`Nc Z4-}7md0#>k3X=c;002ovPDHLkV1h1qbWi{Q delta 511 zcmV|$EDZfIMP9ku_w93?E3894%|kH{)0lFaJ~aV2rv2gQ=+gsJ9!K| z2cSwORdm`JI^0V>?meZe-e-=1e+sgP_|m|LK~y5^l7GUQDX2^}nKt65Q?;^_ltrQA zLl^)6000000002sZTw#P03&6nKUpO1gDX|K_SAqxEK&7zL{BQudmH^09i^30+`n`! zvfI76uT)UmQ-5OzJ%dWkwvvb?-?3{k_GmX~DM4?OOQ5INomtKEtEAf8o<7#Uk~Y;S zi81sOg`%UksyfYe{Nd0gYkRikI0iTNuB7!cc0nBmu~pA!eP$@>J*jQEKd)7gCHmr3 z{M_z+^G4#DxgO>GPz z28@){5C8xG0N%*QrPt#)(m{-|C%MJ!`t05g+(wH2gF>Hhz5_xCF~;g^s}TOrZsi72 z)U zph_lHblMp@+)F<0J*BJOXO4k?3bKdz(!hv8R3ht=f5Mt6s7y7PHsYsKwX&0xMWN$E z7ytkO00000007`^{9gJ1BW0*RStRa*D^8*Xg6pnL2r{wpr_cKS(d$#2`1~>Mur1dg(K^+FMRnKRAW+>@BscpGGuT_vG`r=jP z2f!T92mCDmUe;6FOYNIny};Pqx8$Pv*gYxLPW~I(u6MLfbL-eLv{f@kS-d&Mmbs^` z+DC$ZEutL&00008Uau%!MOooh!Zm*)Jf742TFcip@qa<%<*fLEhKTW3NqF)4_hMF0Q*00000008)jKSX@!bEqbUbN~PV07*qoM6N<$g2CeS A8vpO7EKv5-?n{fXlahEJeC=3__#x3OfZ`A{X z5C*&G76AYN0000000000bn@PN@3o^C@U0!dO14rTyk`Pp_MLOOkqj|50cSgm(d>)4 z2?(+|u$z4`HvuulG3lnWFCt&s0n8|OA*0zBb1NXo(rq{Uwtty>cu)@GQqo&fe- zNe9`0)t@hSX7V@TH+kw`5#@9JLmdGC000000002&?iClCX&`b4B{(er00005D0=5H?BYy#XNkl3_wvOm78$?BXO53NGJ>#1I8`n`ft?( zgAfM0=oSG000000000000Ce)+d+)WQ81Stfz)H4KAG~J*V)mVLx{(YqHUVcljM40i zxd{leIk203F*gA*#WCrovo9iF+5yZccOj$M7jr8h$kJ^$`+v5Xd*r|Hs=@57l4`R5 zVTXj1eHDLcC;N(+15NBgnz#>ZBGtgZTW3M(QgY6Px34)E*nK$5PXg4B7E}V5UjgL> zl73P>u=L)?g;K41RyeIC$3y9|!LnqvZZ*g(0I3~-w|gIT_cXM9$;6nlpxY(OF~`r# zgf<$?+RW<4{C}q3W)-tx_V?cJXS!yb{QE()dkHT_H;49e9BQpvebta}t$@qyth$e- zS8IP%l5FdpbwBUfA7r$KecA6&RAu3XgPPxh&hBj0GM!g$dcmH3H4#{~Zq{a)vz`F< zTuBGnfYqNbcV_Z8;Wv5eUlHYV{X-oA0000000000>=y19n`t0&2qicz00000NkvXX Hu0mjfJY>QW delta 272 zcmdnSyozapay`RGPZ!6KiaBqu#}*w@5MX$)<*pkVu^Z_^G>NSptq$Um?v zm}{zT>HaFNMUgqvr?%!+KK7G5hDkbJC&tGlZ{hH@C{Nt!9mS4@iW5Tcf>@b%z{A-i{Xnr-w UU()^>P>hqo)78&qol`;+0F+9Bg#Z8m diff --git a/tests/ragger/snapshots/nanosp/test_eth2_deposit/00007.png b/tests/ragger/snapshots/nanosp/test_eth2_deposit/00007.png new file mode 100644 index 0000000000000000000000000000000000000000..3a161194e8aa97593f2cd08994f702352935b602 GIT binary patch literal 298 zcmeAS@N?(olHy`uVBq!ia0vp^4M6O`!2~2@x4h5*QXf5C978JRyuBV8x9BVHp_SMnR7=j{cXcM%iMjZE?Ih+yIZ+`uVwr6?ar!{n6Es4wQcunp4;$` oqpDbbHTRAQzxK1k9M15sP5z_#)gXUK`)eREPgg&ebxsLQ05R}{E&u=k literal 0 HcmV?d00001 diff --git a/tests/ragger/snapshots/nanox/test_eth2_deposit/00003.png b/tests/ragger/snapshots/nanox/test_eth2_deposit/00003.png index 520e8bdc691499026b745a05ebc7f5a1e971157a..651b5b5be0ac4beca0351307c24a989978f85149 100644 GIT binary patch delta 923 zcmV;M17!T^1+WK@BYy*TNkl+;|lpz=CsN2!9h0SZ2wIIi)O_Zj3@5+8)9QXMw_kYfS{z(HyjoVq)!j-{I zkH_iE!fK#3iO=B}>9&vS94ZVhj{Bb?qJfN#l16r$1i{O&rx=6q&H~fGc?XEL3T{lQ^ zBWkfTeRdNd>q?iS_-U}H;_Ii&ascc#liOcvmVhAR&VO3ArE0Y!mCApn4kK=yxsU-z zZaN`q{dKCB)jEDKegR){G`Q-$yH!{vpPw#hcM8t3>)x)U*+m4hkf~tQc3?87!5dO# zu%%ohJDb8_)m?h+D}!I@uQ!(e3qHD?z5jzS20zKSZf6W0jML$a!NXuzKM}baDoMAb zxW1?o1Anf4e zT$iUt+^23WNJaJILU0PNiI=O!(-U>g!~N>;TE-Z0o&!<@E~3SG+#+&p*0lBbBv@8? zk$)ni^qHw+(F$Zio*@YGH*a*PltBN&jik+~)ob0rtCOJj0eBuzl8Xh%Sm<9ef~*pV z$a<4D6$N0X+ABXEsd9jQdZd)ZwmOYg`#uR~neYAof?k8d*q>>0mgGjvnzJ>f>Z6;u x`N8Fqky)ws`9ZES0yZk{2SNxTgb)(&4-~7pP5ba2v&8@a002ovPDHLkV1f=8&kO(n delta 722 zcmV;@0xkWp2k8ZnBYy(0Nkl0~S*7vqKW{NGdS z2og|6F=w_7000000L4LliAAe3%a%XaIKeX+JOKqRVr%&65 z^6PeZe<6s$O8&SVF_?_taKvC5aCIV#YN)5?SCev9BK3CVZBEi+8m6fAsA||Bn6hmwZhq|Gcv_=}OD{v&W!(0U=}29HUE4z-{WNA@m-MzQo{ zs@*E*e}5v|tNJpe9DUQK+OzSp2XAz0)=}zRo(vqCj{O5Ls4zF7Fd0R>goqkx+=wOF zu_p9Br_IPd+t4yUDqF^AduU^N^)wCRO1P@pGlt$V5KRIA00000o9EronRs@+p8cQL zg1w+ksQBvnNNGtzqTh-bO@@*!CtU!XZce{8000000Kf!(0CL6}EtUzwCIA2c07*qoM6N<$ Eg4B&#R{#J2 diff --git a/tests/ragger/snapshots/nanox/test_eth2_deposit/00004.png b/tests/ragger/snapshots/nanox/test_eth2_deposit/00004.png index 45411331a9b48053c0ae05f9667ad74dd52f4280..d7b41fb610f7f70321dad15084e6cfa15b39f69d 100644 GIT binary patch delta 795 zcmV+$1LXXe1hEE?BYy(;Nkln7FMnk349IU1Fl5Zm(iW}^ zX1YH}{dnMjEkal}175?e8i}}zt(;)ksuUR{u9k&2h5zjNt z!<+EMbQkM_6Q=aKhg7tLl>w+G{fz5gJL!IS*xcE;dlj1FfEZi8KY5U3iO+}n!IrcY^3iY}$IfxmH^mP_#> zh~_%#d4C^s)*uq2lQN{XA|6KMQqWb$NXr4g2{UTwZA+NeR$DW&h~GlDn7+_;jeriA zKmn+xc1s4Cn1E*cFFRUWZK<1covRDZ-SZ;~&Bp%+n389)e!4ug&J5KaED{uMk*fOv z0P6-7{CFPo_no@SZlmP@I0E+mLq@WxYg*ImHh+Q+3=b>2-p6vpX_j))?A4yXK2SX16qi61tE?~@{iFrRwx z-bbE;4&l%Mq}aOAeU&?ha|2*1^$)6^n>aTB6_2Z)n>hCv>a5z}G4%WmfDl3mA>`Nc Z4-}7md0#>k3X=c;002ovPDHLkV1h1qbWi{Q delta 511 zcmV|$EDZfIMP9ku_w93?E3894%|kH{)0lFaJ~aV2rv2gQ=+gsJ9!K| z2cSwORdm`JI^0V>?meZe-e-=1e+sgP_|m|LK~y5^l7GUQDX2^}nKt65Q?;^_ltrQA zLl^)6000000002sZTw#P03&6nKUpO1gDX|K_SAqxEK&7zL{BQudmH^09i^30+`n`! zvfI76uT)UmQ-5OzJ%dWkwvvb?-?3{k_GmX~DM4?OOQ5INomtKEtEAf8o<7#Uk~Y;S zi81sOg`%UksyfYe{Nd0gYkRikI0iTNuB7!cc0nBmu~pA!eP$@>J*jQEKd)7gCHmr3 z{M_z+^G4#DxgO>GPz z28@){5C8xG0N%*QrPt#)(m{-|C%MJ!`t05g+(wH2gF>Hhz5_xCF~;g^s}TOrZsi72 z)U zph_lHblMp@+)F<0J*BJOXO4k?3bKdz(!hv8R3ht=f5Mt6s7y7PHsYsKwX&0xMWN$E z7ytkO00000007`^{9gJ1BW0*RStRa*D^8*Xg6pnL2r{wpr_cKS(d$#2`1~>Mur1dg(K^+FMRnKRAW+>@BscpGGuT_vG`r=jP z2f!T92mCDmUe;6FOYNIny};Pqx8$Pv*gYxLPW~I(u6MLfbL-eLv{f@kS-d&Mmbs^` z+DC$ZEutL&00008Uau%!MOooh!Zm*)Jf742TFcip@qa<%<*fLEhKTW3NqF)4_hMF0Q*00000008)jKSX@!bEqbUbN~PV07*qoM6N<$g2CeS A8vpO7EKv5-?n{fXlahEJeC=3__#x3OfZ`A{X z5C*&G76AYN0000000000bn@PN@3o^C@U0!dO14rTyk`Pp_MLOOkqj|50cSgm(d>)4 z2?(+|u$z4`HvuulG3lnWFCt&s0n8|OA*0zBb1NXo(rq{Uwtty>cu)@GQqo&fe- zNe9`0)t@hSX7V@TH+kw`5#@9JLmdGC000000002&?iClCX&`b4B{(er00005D0=5H?BYy#XNkl3_wvOm78$?BXO53NGJ>#1I8`n`ft?( zgAfM0=oSG000000000000Ce)+d+)WQ81Stfz)H4KAG~J*V)mVLx{(YqHUVcljM40i zxd{leIk203F*gA*#WCrovo9iF+5yZccOj$M7jr8h$kJ^$`+v5Xd*r|Hs=@57l4`R5 zVTXj1eHDLcC;N(+15NBgnz#>ZBGtgZTW3M(QgY6Px34)E*nK$5PXg4B7E}V5UjgL> zl73P>u=L)?g;K41RyeIC$3y9|!LnqvZZ*g(0I3~-w|gIT_cXM9$;6nlpxY(OF~`r# zgf<$?+RW<4{C}q3W)-tx_V?cJXS!yb{QE()dkHT_H;49e9BQpvebta}t$@qyth$e- zS8IP%l5FdpbwBUfA7r$KecA6&RAu3XgPPxh&hBj0GM!g$dcmH3H4#{~Zq{a)vz`F< zTuBGnfYqNbcV_Z8;Wv5eUlHYV{X-oA0000000000>=y19n`t0&2qicz00000NkvXX Hu0mjfJY>QW delta 272 zcmdnSyozapay`RGPZ!6KiaBqu#}*w@5MX$)<*pkVu^Z_^G>NSptq$Um?v zm}{zT>HaFNMUgqvr?%!+KK7G5hDkbJC&tGlZ{hH@C{Nt!9mS4@iW5Tcf>@b%z{A-i{Xnr-w UU()^>P>hqo)78&qol`;+0F+9Bg#Z8m diff --git a/tests/ragger/snapshots/nanox/test_eth2_deposit/00007.png b/tests/ragger/snapshots/nanox/test_eth2_deposit/00007.png new file mode 100644 index 0000000000000000000000000000000000000000..3a161194e8aa97593f2cd08994f702352935b602 GIT binary patch literal 298 zcmeAS@N?(olHy`uVBq!ia0vp^4M6O`!2~2@x4h5*QXf5C978JRyuBV8x9BVHp_SMnR7=j{cXcM%iMjZE?Ih+yIZ+`uVwr6?ar!{n6Es4wQcunp4;$` oqpDbbHTRAQzxK1k9M15sP5z_#)gXUK`)eREPgg&ebxsLQ05R}{E&u=k literal 0 HcmV?d00001 diff --git a/tests/ragger/snapshots/stax/test_eth2_deposit/00001.png b/tests/ragger/snapshots/stax/test_eth2_deposit/00001.png index 6e06b69d6dde3a4fa0a7b5422389f5229b32babd..90e4cbfea108b36826c8b63abd9b24055884d855 100644 GIT binary patch literal 13305 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 literal 20472 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 HuJQi?t7V=R literal 8277 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 ZCla_`86@bvvhD$}ju=_TOc@jhp}g From 42b667ed973c1dd97ed3d8b6576f749c619b7251 Mon Sep 17 00:00:00 2001 From: Charles-Edouard de la Vergne Date: Wed, 13 May 2026 08:51:21 +0200 Subject: [PATCH 15/29] fix: Size the GCS pairs allocation with the right element type ui_pairs_init() allocates the per-pair array with `nbPairs * sizeof(nbgl_contentTagValueList_t)` but g_pairs is typed as `nbgl_contentTagValue_t *`. The list struct is roughly three times the size of one tag-value entry, so each pair was being over-allocated by the size difference, wasting app-memory pool space on every generic-clear-signing review without any functional benefit. Use `sizeof(nbgl_contentTagValue_t)` instead so the allocation matches what the surrounding code reads and writes. Co-Authored-By: Claude Opus 4.7 --- src/nbgl/ui_utils.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/nbgl/ui_utils.c b/src/nbgl/ui_utils.c index c2d855d89..31774d9e2 100644 --- a/src/nbgl/ui_utils.c +++ b/src/nbgl/ui_utils.c @@ -49,7 +49,7 @@ bool ui_pairs_init(uint8_t nbPairs) { } // Allocate the pairs memory - if (!APP_MEM_CALLOC((void **) &g_pairs, nbPairs * sizeof(nbgl_contentTagValueList_t))) { + if (!APP_MEM_CALLOC((void **) &g_pairs, nbPairs * sizeof(nbgl_contentTagValue_t))) { goto error; } g_pairsList->nbPairs = nbPairs; From 8d61fdc7c3ca20dd45ca88fbb1254fb911fb1e4b Mon Sep 17 00:00:00 2001 From: Charles-Edouard de la Vergne Date: Wed, 13 May 2026 08:51:40 +0200 Subject: [PATCH 16/29] fix: Make HAVE_CHALLENGE_NO_CHECK builds noisy at compile time MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit cmd_get_challenge.c uses `#ifdef HAVE_CHALLENGE_NO_CHECK` to (a) seed the rolling challenge with a hardcoded constant and (b) skip the verification of host-supplied challenges. The flag is meant for test runs, but nothing in the source surfaced its presence to a release build — a stray CHALLENGE_NO_CHECK=1 in a Makefile invocation would ship a binary that accepts arbitrary challenge values without any trace in the build log. Emit a `#warning` whenever the macro is defined, so the build log shows the bypass and CI can grep for it before promoting an artifact to release. Co-Authored-By: Claude Opus 4.7 --- src/features/get_challenge/cmd_get_challenge.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/features/get_challenge/cmd_get_challenge.c b/src/features/get_challenge/cmd_get_challenge.c index f4dee5848..5349e928a 100644 --- a/src/features/get_challenge/cmd_get_challenge.c +++ b/src/features/get_challenge/cmd_get_challenge.c @@ -3,6 +3,11 @@ #include "apdu_constants.h" #include "challenge.h" +#ifdef HAVE_CHALLENGE_NO_CHECK +#warning \ + "HAVE_CHALLENGE_NO_CHECK is enabled: challenge generation is deterministic and challenge verification is bypassed. This must never reach a release build." +#endif + static uint32_t challenge; /** From 62e1397ca45e2980f48df15d87e0c373402e6468 Mon Sep 17 00:00:00 2001 From: Charles-Edouard de la Vergne Date: Wed, 13 May 2026 08:52:17 +0200 Subject: [PATCH 17/29] fix: Reject oversize GCS constraint values instead of truncating MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit handle_param_constraint() assigned `data->value.size` (uint16_t from the TLV) into the constraint node's `size` field, which is uint8_t. Anything over 255 bytes silently truncated to `size mod 256`. The buffer itself is allocated with the full uint16 size and the payload is copied in full, so no OOB occurs, but the truncated `node->size` later drives `bytes_to_lowercase_hex()` in check_bytes_constraint(), which then formats only `size mod 256` bytes — the constraint comparison silently never matches and the visibility filter behaves as if no constraint was set. Reject any constraint payload past UINT8_MAX before assigning, so a malformed descriptor is surfaced as an error instead of becoming a silent visibility bypass. Co-Authored-By: Claude Opus 4.7 --- src/features/generic_tx_parser/gtp_field.c | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/src/features/generic_tx_parser/gtp_field.c b/src/features/generic_tx_parser/gtp_field.c index 5c791a240..84611ff87 100644 --- a/src/features/generic_tx_parser/gtp_field.c +++ b/src/features/generic_tx_parser/gtp_field.c @@ -120,13 +120,20 @@ static bool handle_param_constraint(const tlv_data_t *data, s_field_ctx *context PRINTF("Error: Empty constraint value!\n"); return false; } + // node->size is uint8_t; reject larger constraints rather than truncating + // (truncated size would later make the constraint-matching comparison + // silently always fail). + if (data->value.size > UINT8_MAX) { + PRINTF("Error: Constraint value too large (%d > %d)!\n", (int) data->value.size, UINT8_MAX); + return false; + } // Allocate new constraint node s_field_constraint *node = NULL; if (APP_MEM_CALLOC((void **) &node, sizeof(s_field_constraint)) == false) { PRINTF("Error: Failed to allocate memory for constraint node!\n"); return false; } - node->size = data->value.size; + node->size = (uint8_t) data->value.size; // Allocate value buffer if (APP_MEM_CALLOC((void **) &node->value, data->value.size) == false) { PRINTF("Error: Failed to allocate memory for constraint value!\n"); From c8f29c78c0a5c804900fcbefad7ad26486e0409c Mon Sep 17 00:00:00 2001 From: Charles-Edouard de la Vergne Date: Wed, 13 May 2026 08:52:48 +0200 Subject: [PATCH 18/29] fix: Iterate the internal plugin table by length instead of a phantom sentinel MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The PLUGIN_TYPE_OLD_INTERNAL branch of eth_plugin_call() walked INTERNAL_ETH_PLUGINS with an open-ended `for (i = 0;; i++)` loop and broke out when `alias[0] == 0`. The array initializer never emits a zero-byte sentinel — its last entry is "-eip7251" — so the only way the break could fire was the loop reading past the end of the array into adjacent .rodata and happening to land on a zero byte. Any non-zero byte in that adjacent memory turns the loop into an out-of- bounds dereference and an attempt to call PIC() on garbage. Bound the loop by ARRAYLEN(INTERNAL_ETH_PLUGINS) so iteration stays inside the table regardless of how its initializer is extended. Co-Authored-By: Claude Opus 4.7 --- src/plugins/eth_plugin_handler.c | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/src/plugins/eth_plugin_handler.c b/src/plugins/eth_plugin_handler.c index c73546909..cd61ed30d 100644 --- a/src/plugins/eth_plugin_handler.c +++ b/src/plugins/eth_plugin_handler.c @@ -336,10 +336,7 @@ eth_plugin_result_t eth_plugin_call(int method, void *parameter) { } case PLUGIN_TYPE_OLD_INTERNAL: { // Perform the call - for (i = 0;; i++) { - if (INTERNAL_ETH_PLUGINS[i].alias[0] == 0) { - break; - } + for (i = 0; i < ARRAYLEN(INTERNAL_ETH_PLUGINS); i++) { if (strcmp(alias, INTERNAL_ETH_PLUGINS[i].alias) == 0) { ((PluginCall) PIC(INTERNAL_ETH_PLUGINS[i].impl))(method, parameter); break; From 77c7cac2c07b388680caf947cff1a7ea33b8861b Mon Sep 17 00:00:00 2001 From: Charles-Edouard de la Vergne Date: Wed, 13 May 2026 08:53:13 +0200 Subject: [PATCH 19/29] fix: Propagate hash_filtering_path() failures instead of swallowing them The 11 EIP-712 filter command handlers (calldata value/callee/chain- id/selector/amount/spender, plus the various other filter kinds) called hash_filtering_path() purely for its side effect on the signature-verification hash and ignored its bool return. When the helper bails on path_get_nth_field()/ui_712_get_discarded_path() returning NULL, the hash context is left mid-update; the subsequent sig_verif_end() then verifies an incomplete hash against the host- supplied signature. The downstream signature check still catches the mismatch in practice, so this isn't a bypass, but it produces a generic "signature failed" error several lines later instead of identifying the actual problem. Wrap each call site in `if (!hash_filtering_path(...)) return false;` so the failure is surfaced at the point where the inconsistency appears. Co-Authored-By: Claude Opus 4.7 --- src/features/sign_message_eip712/filtering.c | 44 +++++++++++++++----- 1 file changed, 33 insertions(+), 11 deletions(-) diff --git a/src/features/sign_message_eip712/filtering.c b/src/features/sign_message_eip712/filtering.c index e9a84b430..26d88ae51 100644 --- a/src/features/sign_message_eip712/filtering.c +++ b/src/features/sign_message_eip712/filtering.c @@ -362,7 +362,9 @@ bool filtering_calldata_spender(const uint8_t *payload, if (!sig_verif_start(&hash_ctx, FILT_MAGIC_CALLDATA_SPENDER)) { return false; } - hash_filtering_path((cx_hash_t *) &hash_ctx, discarded, path_crc); + if (!hash_filtering_path((cx_hash_t *) &hash_ctx, discarded, path_crc)) { + return false; + } hash_byte(index, (cx_hash_t *) &hash_ctx); if (!sig_verif_end(&hash_ctx, sig, sig_len)) { return false; @@ -421,7 +423,9 @@ bool filtering_calldata_amount(const uint8_t *payload, if (!sig_verif_start(&hash_ctx, FILT_MAGIC_CALLDATA_AMOUNT)) { return false; } - hash_filtering_path((cx_hash_t *) &hash_ctx, discarded, path_crc); + if (!hash_filtering_path((cx_hash_t *) &hash_ctx, discarded, path_crc)) { + return false; + } hash_byte(index, (cx_hash_t *) &hash_ctx); if (!sig_verif_end(&hash_ctx, sig, sig_len)) { return false; @@ -480,7 +484,9 @@ bool filtering_calldata_selector(const uint8_t *payload, if (!sig_verif_start(&hash_ctx, FILT_MAGIC_CALLDATA_SELECTOR)) { return false; } - hash_filtering_path((cx_hash_t *) &hash_ctx, discarded, path_crc); + if (!hash_filtering_path((cx_hash_t *) &hash_ctx, discarded, path_crc)) { + return false; + } hash_byte(index, (cx_hash_t *) &hash_ctx); if (!sig_verif_end(&hash_ctx, sig, sig_len)) { return false; @@ -539,7 +545,9 @@ bool filtering_calldata_chain_id(const uint8_t *payload, if (!sig_verif_start(&hash_ctx, FILT_MAGIC_CALLDATA_CHAIN_ID)) { return false; } - hash_filtering_path((cx_hash_t *) &hash_ctx, discarded, path_crc); + if (!hash_filtering_path((cx_hash_t *) &hash_ctx, discarded, path_crc)) { + return false; + } hash_byte(index, (cx_hash_t *) &hash_ctx); if (!sig_verif_end(&hash_ctx, sig, sig_len)) { return false; @@ -598,7 +606,9 @@ bool filtering_calldata_callee(const uint8_t *payload, if (!sig_verif_start(&hash_ctx, FILT_MAGIC_CALLDATA_CALLEE)) { return false; } - hash_filtering_path((cx_hash_t *) &hash_ctx, discarded, path_crc); + if (!hash_filtering_path((cx_hash_t *) &hash_ctx, discarded, path_crc)) { + return false; + } hash_byte(index, (cx_hash_t *) &hash_ctx); if (!sig_verif_end(&hash_ctx, sig, sig_len)) { return false; @@ -657,7 +667,9 @@ bool filtering_calldata_value(const uint8_t *payload, if (!sig_verif_start(&hash_ctx, FILT_MAGIC_CALLDATA_VALUE)) { return false; } - hash_filtering_path((cx_hash_t *) &hash_ctx, discarded, path_crc); + if (!hash_filtering_path((cx_hash_t *) &hash_ctx, discarded, path_crc)) { + return false; + } hash_byte(index, (cx_hash_t *) &hash_ctx); if (!sig_verif_end(&hash_ctx, sig, sig_len)) { return false; @@ -930,7 +942,9 @@ bool filtering_trusted_name(const uint8_t *payload, if (!sig_verif_start(&hash_ctx, FILT_MAGIC_TRUSTED_NAME)) { return false; } - hash_filtering_path((cx_hash_t *) &hash_ctx, discarded, path_crc); + if (!hash_filtering_path((cx_hash_t *) &hash_ctx, discarded, path_crc)) { + return false; + } hash_nbytes((uint8_t *) name, sizeof(char) * name_len, (cx_hash_t *) &hash_ctx); hash_nbytes((uint8_t *) types, type_count, (cx_hash_t *) &hash_ctx); hash_nbytes((uint8_t *) sources, source_count, (cx_hash_t *) &hash_ctx); @@ -997,7 +1011,9 @@ bool filtering_date_time(const uint8_t *payload, if (!sig_verif_start(&hash_ctx, FILT_MAGIC_DATETIME)) { return false; } - hash_filtering_path((cx_hash_t *) &hash_ctx, discarded, path_crc); + if (!hash_filtering_path((cx_hash_t *) &hash_ctx, discarded, path_crc)) { + return false; + } hash_nbytes((uint8_t *) name, sizeof(char) * name_len, (cx_hash_t *) &hash_ctx); if (!sig_verif_end(&hash_ctx, sig, sig_len)) { return false; @@ -1056,7 +1072,9 @@ bool filtering_amount_join_token(const uint8_t *payload, if (!sig_verif_start(&hash_ctx, FILT_MAGIC_AMOUNT_JOIN_TOKEN)) { return false; } - hash_filtering_path((cx_hash_t *) &hash_ctx, discarded, path_crc); + if (!hash_filtering_path((cx_hash_t *) &hash_ctx, discarded, path_crc)) { + return false; + } hash_byte(join_id, (cx_hash_t *) &hash_ctx); if (!sig_verif_end(&hash_ctx, sig, sig_len)) { return false; @@ -1127,7 +1145,9 @@ bool filtering_amount_join_value(const uint8_t *payload, if (!sig_verif_start(&hash_ctx, FILT_MAGIC_AMOUNT_JOIN_VALUE)) { return false; } - hash_filtering_path((cx_hash_t *) &hash_ctx, discarded, path_crc); + if (!hash_filtering_path((cx_hash_t *) &hash_ctx, discarded, path_crc)) { + return false; + } hash_nbytes((uint8_t *) name, sizeof(char) * name_len, (cx_hash_t *) &hash_ctx); hash_byte(join_id, (cx_hash_t *) &hash_ctx); if (!sig_verif_end(&hash_ctx, sig, sig_len)) { @@ -1198,7 +1218,9 @@ bool filtering_raw_field(const uint8_t *payload, if (!sig_verif_start(&hash_ctx, FILT_MAGIC_RAW_FIELD)) { return false; } - hash_filtering_path((cx_hash_t *) &hash_ctx, discarded, path_crc); + if (!hash_filtering_path((cx_hash_t *) &hash_ctx, discarded, path_crc)) { + return false; + } hash_nbytes((uint8_t *) name, sizeof(char) * name_len, (cx_hash_t *) &hash_ctx); if (!sig_verif_end(&hash_ctx, sig, sig_len)) { return false; From 0a1cc29f3404d70c6d3ae220473d83eb878ad492 Mon Sep 17 00:00:00 2001 From: Charles-Edouard de la Vergne Date: Wed, 13 May 2026 08:53:39 +0200 Subject: [PATCH 20/29] fix: Bound OWNER_DERIV_PATH length locally before passing to bip32_path_read handle_owner_deriv_path() assigned the host-supplied length byte straight into context->owner_deriv_path.length and forwarded it to bip32_path_read(), whose internal guard already rejects out_len > MAX_BIP32_PATH. The OOB write is therefore unreachable in practice, but the code reads as if the length were trusted and relies on an SDK invariant that lives in a separate translation unit. Validate the length against MAX_BIP32_PATH in the handler itself, rejecting both 0 and any value larger than the fixed-size path buffer, so the bound is enforced locally rather than implicitly. Co-Authored-By: Claude Opus 4.7 --- src/features/provide_trusted_name/trusted_name.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/src/features/provide_trusted_name/trusted_name.c b/src/features/provide_trusted_name/trusted_name.c index 4972d8467..dcfe737f9 100644 --- a/src/features/provide_trusted_name/trusted_name.c +++ b/src/features/provide_trusted_name/trusted_name.c @@ -411,7 +411,13 @@ static bool handle_owner_deriv_path(const tlv_data_t *data, s_trusted_name_ctx * PRINTF("OWNER: failed to extract\n"); return false; } - context->owner_deriv_path.length = field.ptr[0]; + // Validate the host-supplied length against the fixed-size path buffer before any assignment. + uint8_t deriv_length = field.ptr[0]; + if (deriv_length == 0 || deriv_length > MAX_BIP32_PATH) { + PRINTF("OWNER_DERIV_PATH: invalid length %u\n", deriv_length); + return false; + } + context->owner_deriv_path.length = deriv_length; if (!bip32_path_read(&field.ptr[sizeof(context->owner_deriv_path.length)], field.size - sizeof(context->owner_deriv_path.length), context->owner_deriv_path.path, From f8be5a81f785f84455bb13be94b0a28e1d3c13bb Mon Sep 17 00:00:00 2001 From: Charles-Edouard de la Vergne Date: Wed, 13 May 2026 09:16:01 +0200 Subject: [PATCH 21/29] fix: Reject empty plugin name in handle_set_external_plugin MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit handle_set_external_plugin() trusted the host-supplied length byte end-to-end: a zero-length name passed every existing check, the SHA-256 hash was computed over an empty name prefix, and only the Ledger PKI signature verification stood between the request and a plugin registration with pluginName = "". The downstream alias matching uses strcmp() against entries like "-erc20", so an empty alias would never match any internal plugin and the registration would be inert — but the device would still have stored a useless plugin context and surfaced a stale name on subsequent screens. Reject pluginNameLength == 0 explicitly before any further work. This is defense in depth against a backend that signs a malformed payload, not a bypass of the PKI gate. Co-Authored-By: Claude Opus 4.7 --- .../set_external_plugin/cmd_set_external_plugin.c | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/src/features/set_external_plugin/cmd_set_external_plugin.c b/src/features/set_external_plugin/cmd_set_external_plugin.c index 81bab8ca4..83e4d9e95 100644 --- a/src/features/set_external_plugin/cmd_set_external_plugin.c +++ b/src/features/set_external_plugin/cmd_set_external_plugin.c @@ -12,6 +12,14 @@ uint16_t handle_set_external_plugin(const uint8_t *workBuffer, uint8_t dataLengt uint32_t params[2]; PRINTF("plugin Name Length: %d\n", pluginNameLength); + // Reject empty plugin names locally. The payload is also signed by Ledger + // PKI and a backend should never sign an empty name, but enforcing the + // bound here keeps the device side self-consistent and avoids depending + // on a backend invariant we can't observe. + if (pluginNameLength == 0) { + PRINTF("empty plugin name\n"); + return SWO_INCORRECT_DATA; + } const size_t payload_size = 1 + pluginNameLength + ADDRESS_LENGTH + SELECTOR_SIZE; if (dataLength <= payload_size) { From d03d28bfa85c3f43ff38f2f741c27af1feb5d477 Mon Sep 17 00:00:00 2001 From: Charles-Edouard de la Vergne Date: Wed, 13 May 2026 09:16:34 +0200 Subject: [PATCH 22/29] fix: Validate Exchange address_parameters before dereferencing handle_check_address() read params->address_parameters[0] without first checking that the pointer was non-NULL or that address_parameters_length covered at least the length byte. The function is reachable only from the Exchange app via os_lib_call(), so this isn't exploitable from a host APDU today, but the contract between the two libraries lives across a trust boundary and would silently OOB-read on any future caller that wires up the same interface less carefully. Reject params->address_parameters == NULL and address_parameters_length < 1 early so the function is safe regardless of who calls it. Co-Authored-By: Claude Opus 4.7 --- src/swap/handle_check_address.c | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/src/swap/handle_check_address.c b/src/swap/handle_check_address.c index 9a9dce0f9..81c5119a3 100644 --- a/src/swap/handle_check_address.c +++ b/src/swap/handle_check_address.c @@ -13,6 +13,15 @@ void handle_check_address(check_address_parameters_t* params, chain_config_t* ch PRINTF("Address to check == 0\n"); return; } + // The caller (Exchange app, signed by Ledger) is the only path into this + // function, so address_parameters comes from a trusted source. Validate + // anyway: if a future caller wires up handle_check_address from a less + // trusted context, these checks prevent out-of-bounds reads on the + // length byte and unsafe overshoot into bip32_path_read. + if (params->address_parameters == NULL || params->address_parameters_length == 0) { + PRINTF("Empty address_parameters\n"); + return; + } char address[ADDRESS_LENGTH_STR]; uint8_t raw_pubkey[CX_SECP256_PUB_KEY_SIZE]; From 453b7a3f110ad18941f017249208d71f6a15ef45 Mon Sep 17 00:00:00 2001 From: Charles-Edouard de la Vergne Date: Wed, 13 May 2026 09:17:30 +0200 Subject: [PATCH 23/29] fix: Make rlp_decode_length() self-bounded with an explicit bufferLength MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit rlp_decode_length() dereferenced its `buffer` argument and then indexed up to four bytes past the prefix without any length parameter. Safety relied entirely on the caller running rlp_can_decode() first — a sibling helper that does check bufferLength. The single in-tree caller (eth_ustream.c) follows that discipline, but a future call site that skipped rlp_can_decode would silently OOB-read into adjacent memory. Add a bufferLength parameter to rlp_decode_length(), reject zero- length input up front, and reject inputs shorter than the encoded length prefix in the long-string / long-list branches. Update the existing caller to pass context->rlpBufferPos. The function now upholds its own invariant instead of relying on its companion. Co-Authored-By: Claude Opus 4.7 --- src/features/sign_tx/eth_ustream.c | 1 + src/features/sign_tx/rlp_utils.c | 19 ++++++++++++++++++- src/features/sign_tx/rlp_utils.h | 11 +++++++++-- 3 files changed, 28 insertions(+), 3 deletions(-) diff --git a/src/features/sign_tx/eth_ustream.c b/src/features/sign_tx/eth_ustream.c index ee8f96d16..05fc9574a 100644 --- a/src/features/sign_tx/eth_ustream.c +++ b/src/features/sign_tx/eth_ustream.c @@ -609,6 +609,7 @@ static parserStatus_e parse_rlp(txContext_t *context) { } // Ready to process this field if (!rlp_decode_length(context->rlpBuffer, + context->rlpBufferPos, &context->currentFieldLength, &offset, &context->currentFieldIsList)) { diff --git a/src/features/sign_tx/rlp_utils.c b/src/features/sign_tx/rlp_utils.c index 30fce996a..d51942be8 100644 --- a/src/features/sign_tx/rlp_utils.c +++ b/src/features/sign_tx/rlp_utils.c @@ -54,7 +54,18 @@ bool rlp_can_decode(uint8_t *buffer, uint32_t bufferLength, bool *valid) { return true; } -bool rlp_decode_length(uint8_t *buffer, uint32_t *fieldLength, uint32_t *offset, bool *list) { +bool rlp_decode_length(uint8_t *buffer, + uint32_t bufferLength, + uint32_t *fieldLength, + uint32_t *offset, + bool *list) { + // The shortest valid RLP encoding is one byte; longer encodings need + // additional bytes after the prefix. Each branch below double-checks the + // exact requirement for its case, but reject an empty buffer up front so + // we never dereference `*buffer` on no input. + if (bufferLength == 0) { + return false; + } if (*buffer <= RLP_SINGLE_BYTE_MAX) { *offset = 0; *fieldLength = 1; @@ -65,6 +76,9 @@ bool rlp_decode_length(uint8_t *buffer, uint32_t *fieldLength, uint32_t *offset, *list = false; } else if (*buffer <= RLP_LONG_STRING_MAX) { *offset = 1 + (*buffer - RLP_LONG_STRING_BASE); + if (bufferLength < *offset) { + return false; + } *list = false; switch (*buffer) { case RLP_STR_LEN_OF_BYTES_1: @@ -90,6 +104,9 @@ bool rlp_decode_length(uint8_t *buffer, uint32_t *fieldLength, uint32_t *offset, *list = true; } else { *offset = 1 + (*buffer - RLP_LONG_LIST_BASE); + if (bufferLength < *offset) { + return false; + } *list = true; switch (*buffer) { case RLP_LIST_LEN_OF_BYTES_1: diff --git a/src/features/sign_tx/rlp_utils.h b/src/features/sign_tx/rlp_utils.h index eb78234fd..e2608f1e2 100644 --- a/src/features/sign_tx/rlp_utils.h +++ b/src/features/sign_tx/rlp_utils.h @@ -55,13 +55,20 @@ * @brief Decode an RLP encoded field - see * https://github.com/ethereum/wiki/wiki/RLP * @param [in] buffer buffer containing the RLP encoded field to decode + * @param [in] bufferLength number of bytes readable starting from buffer; the + * function reads at most 5 bytes (1 prefix + 4 length bytes for the longest + * RLP encoding) * @param [out] fieldLength length of the RLP encoded field * @param [out] offset offset to the beginning of the RLP encoded field from the * buffer * @param [out] list true if the field encodes a list, false if it encodes a * string - * @return true if the RLP header is consistent + * @return true if the RLP header is consistent and fits within bufferLength */ -bool rlp_decode_length(uint8_t *buffer, uint32_t *fieldLength, uint32_t *offset, bool *list); +bool rlp_decode_length(uint8_t *buffer, + uint32_t bufferLength, + uint32_t *fieldLength, + uint32_t *offset, + bool *list); bool rlp_can_decode(uint8_t *buffer, uint32_t bufferLength, bool *valid); From 78bc54695e41ddbc905611b5be0c336c96e10bce Mon Sep 17 00:00:00 2001 From: Charles-Edouard de la Vergne Date: Wed, 13 May 2026 09:26:19 +0200 Subject: [PATCH 24/29] fix: Cap PARAM_TYPE_GROUP nesting depth in the GCS formatter MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit format_field() and format_param_group() in the generic-clear-signing formatter are mutually recursive: a PARAM_TYPE_GROUP entry recurses through every sub-field, and a nested PARAM_TYPE_GROUP recurses again. The only existing bound is the per-APDU TLV buffer size, which still leaves room for a couple hundred nesting levels — enough to walk through several KB of device stack with a hostile descriptor on the Nano S+ where total stack is tight. Thread an explicit `depth` parameter through format_field() and format_param_group(): the top-level call from cmd_field.c starts at 0, and format_param_group() bumps it before recursing. When depth reaches MAX_PARAM_GROUP_DEPTH (8), the formatter refuses the descriptor. Eight nesting levels is well past any realistic GCS layout and keeps the worst-case stack usage of this code path bounded. The unit-test mock for format_field() is updated to match the new signature, and a regression test asserts that the cap short-circuits before any sub-field is visited. Co-Authored-By: Claude Opus 4.7 --- src/features/generic_tx_parser/cmd_field.c | 2 +- src/features/generic_tx_parser/gtp_field.c | 4 +-- src/features/generic_tx_parser/gtp_field.h | 2 +- .../generic_tx_parser/gtp_param_group.c | 28 +++++++++++++-- .../generic_tx_parser/gtp_param_group.h | 2 +- tests/fuzzing/harness/fuzz_generic_parser.c | 2 +- tests/unit/src/test_param_group.c | 35 +++++++++++++++---- 7 files changed, 60 insertions(+), 15 deletions(-) diff --git a/src/features/generic_tx_parser/cmd_field.c b/src/features/generic_tx_parser/cmd_field.c index 910b4f6a0..90860489f 100644 --- a/src/features/generic_tx_parser/cmd_field.c +++ b/src/features/generic_tx_parser/cmd_field.c @@ -27,7 +27,7 @@ static bool handle_tlv_payload(const buffer_t *buf) { cleanup_field(&field); return false; } - if (!format_field(&field)) { + if (!format_field(&field, 0)) { return false; } while (((appState == APP_STATE_SIGNING_EIP712) || !tx_ctx_is_root()) && diff --git a/src/features/generic_tx_parser/gtp_field.c b/src/features/generic_tx_parser/gtp_field.c index 84611ff87..ca5ecd663 100644 --- a/src/features/generic_tx_parser/gtp_field.c +++ b/src/features/generic_tx_parser/gtp_field.c @@ -250,7 +250,7 @@ bool verify_field_struct(const s_field_ctx *context) { return true; } -bool format_field(s_field *field) { +bool format_field(s_field *field, uint8_t depth) { bool ret; switch (field->param_type) { @@ -291,7 +291,7 @@ bool format_field(s_field *field) { ret = format_param_network(&field->param_network, field->name); break; case PARAM_TYPE_GROUP: - ret = format_param_group(field); + ret = format_param_group(field, depth); cleanup_param_group(&field->param_group); break; default: diff --git a/src/features/generic_tx_parser/gtp_field.h b/src/features/generic_tx_parser/gtp_field.h index 25453590f..28345946a 100644 --- a/src/features/generic_tx_parser/gtp_field.h +++ b/src/features/generic_tx_parser/gtp_field.h @@ -85,6 +85,6 @@ typedef struct { bool handle_field_struct(const buffer_t *buf, s_field_ctx *context); bool verify_field_struct(const s_field_ctx *context); -bool format_field(s_field *field); +bool format_field(s_field *field, uint8_t depth); void cleanup_field_constraints(s_field *field); void cleanup_field(s_field *field); diff --git a/src/features/generic_tx_parser/gtp_param_group.c b/src/features/generic_tx_parser/gtp_param_group.c index 472fd9f90..7964115d0 100644 --- a/src/features/generic_tx_parser/gtp_param_group.c +++ b/src/features/generic_tx_parser/gtp_param_group.c @@ -76,7 +76,27 @@ bool handle_param_group_struct(const buffer_t *buf, s_param_group_context *conte // Formatting // ============================================================================= -bool format_param_group(const s_field *field) { +// Cap on nested PARAM_TYPE_GROUP levels to bound the recursion between +// format_field() and format_param_group() on hostile descriptors. +#define MAX_PARAM_GROUP_DEPTH 8 + +/** + * @brief Render every sub-field of a PARAM_TYPE_GROUP field. + * + * Walks the linked list of sub-fields and dispatches each one back through + * format_field(), which may recurse into this function for nested groups. + * + * @param[in] field outer field whose param_group is being rendered + * @param[in] depth current nesting level; pass 0 from the top-level + * format_field() call site (cmd_field.c). format_field() + * forwards this value unchanged, so the increment happens + * here when descending into sub-fields. Calls with + * `depth >= MAX_PARAM_GROUP_DEPTH` are refused to bound + * the worst-case stack usage on hostile descriptors. + * @return true if every sub-field rendered, false on depth-cap, unsupported + * iteration type, or any sub-field failure (short-circuit) + */ +bool format_param_group(const s_field *field, uint8_t depth) { const s_param_group *group = &field->param_group; if (group->iteration_type == GROUP_ITER_BUNDLED) { @@ -84,9 +104,13 @@ bool format_param_group(const s_field *field) { return false; } + if (depth >= MAX_PARAM_GROUP_DEPTH) { + PRINTF("GROUP: nesting too deep (>= %u)\n", MAX_PARAM_GROUP_DEPTH); + return false; + } for (s_group_field_node *n = group->fields; n != NULL; n = (s_group_field_node *) n->node.next) { - if (!format_field(n->field)) { + if (!format_field(n->field, depth + 1)) { return false; } } diff --git a/src/features/generic_tx_parser/gtp_param_group.h b/src/features/generic_tx_parser/gtp_param_group.h index 83f3d009b..8f10171c7 100644 --- a/src/features/generic_tx_parser/gtp_param_group.h +++ b/src/features/generic_tx_parser/gtp_param_group.h @@ -31,5 +31,5 @@ typedef struct { } s_param_group_context; bool handle_param_group_struct(const buffer_t *buf, s_param_group_context *context); -bool format_param_group(const struct s_field *field); +bool format_param_group(const struct s_field *field, uint8_t depth); void cleanup_param_group(s_param_group *group); diff --git a/tests/fuzzing/harness/fuzz_generic_parser.c b/tests/fuzzing/harness/fuzz_generic_parser.c index c9af07da0..fb2bd7451 100644 --- a/tests/fuzzing/harness/fuzz_generic_parser.c +++ b/tests/fuzzing/harness/fuzz_generic_parser.c @@ -26,7 +26,7 @@ int fuzzGenericParserFieldCmd(const uint8_t *data, size_t size) { } // format_field() always cleans up constraints internally (success or failure) - return format_field(&field); + return format_field(&field, 0); } int fuzzGenericParserTxInfoCmd(const uint8_t *data, size_t size) { diff --git a/tests/unit/src/test_param_group.c b/tests/unit/src/test_param_group.c index b7ae17007..be0f521a6 100644 --- a/tests/unit/src/test_param_group.c +++ b/tests/unit/src/test_param_group.c @@ -21,8 +21,9 @@ // Mock functions // ============================================================================= -bool __wrap_format_field(s_field *field) { +bool __wrap_format_field(s_field *field, uint8_t depth) { check_expected(field->name); + check_expected(depth); return (bool) mock(); } @@ -86,7 +87,7 @@ static void test_group_empty(void **state) { (void) state; s_field outer = make_group_field(GROUP_ITER_SEQUENTIAL, NULL); // No sub-fields: format_field must never be called. - assert_true(format_param_group(&outer)); + assert_true(format_param_group(&outer, 0)); } static void test_group_sequential_one_subfield(void **state) { @@ -96,9 +97,10 @@ static void test_group_sequential_one_subfield(void **state) { s_field outer = make_group_field(GROUP_ITER_SEQUENTIAL, &node); expect_string(__wrap_format_field, field->name, "Amount"); + expect_value(__wrap_format_field, depth, 1); will_return(__wrap_format_field, true); - assert_true(format_param_group(&outer)); + assert_true(format_param_group(&outer, 0)); } static void test_group_sequential_two_subfields(void **state) { @@ -109,13 +111,15 @@ static void test_group_sequential_two_subfields(void **state) { MAKE_NODE(node1, &sub1, &node2); s_field outer = make_group_field(GROUP_ITER_SEQUENTIAL, &node1); - // Both sub-fields called in declaration order. + // Both sub-fields called in declaration order with the depth bumped by 1. expect_string(__wrap_format_field, field->name, "Token ID"); + expect_value(__wrap_format_field, depth, 1); will_return(__wrap_format_field, true); expect_string(__wrap_format_field, field->name, "Value"); + expect_value(__wrap_format_field, depth, 1); will_return(__wrap_format_field, true); - assert_true(format_param_group(&outer)); + assert_true(format_param_group(&outer, 0)); } /** @@ -131,7 +135,7 @@ static void test_group_bundled_rejected(void **state) { s_field outer = make_group_field(GROUP_ITER_BUNDLED, &node1); // format_field must never be called when iteration type is BUNDLED. - assert_false(format_param_group(&outer)); + assert_false(format_param_group(&outer, 0)); } static void test_group_subfield_failure_propagates(void **state) { @@ -144,9 +148,25 @@ static void test_group_subfield_failure_propagates(void **state) { // First sub-field fails; second must never be called. expect_string(__wrap_format_field, field->name, "Token ID"); + expect_value(__wrap_format_field, depth, 1); will_return(__wrap_format_field, false); - assert_false(format_param_group(&outer)); + assert_false(format_param_group(&outer, 0)); +} + +/** + * Passing a depth at or above the cap must short-circuit before any sub-field + * is visited. format_field() must never be invoked. + */ +static void test_group_depth_cap_rejects(void **state) { + (void) state; + MAKE_FIELD(sub, "Amount", PARAM_TYPE_RAW); + MAKE_NODE(node, &sub, NULL); + s_field outer = make_group_field(GROUP_ITER_SEQUENTIAL, &node); + + // 8 = MAX_PARAM_GROUP_DEPTH. No expect/will_return: format_field is + // unreachable when the cap fires. + assert_false(format_param_group(&outer, 8)); } // ============================================================================= @@ -160,6 +180,7 @@ int main(void) { cmocka_unit_test(test_group_sequential_two_subfields), cmocka_unit_test(test_group_bundled_rejected), cmocka_unit_test(test_group_subfield_failure_propagates), + cmocka_unit_test(test_group_depth_cap_rejects), }; return cmocka_run_group_tests(tests, NULL, NULL); } From df99ad4ae3cd95b942da533cf7f25abbdea157ee Mon Sep 17 00:00:00 2001 From: Charles-Edouard de la Vergne Date: Wed, 13 May 2026 09:42:13 +0200 Subject: [PATCH 25/29] fix: Lock EIP-712 type system at FILT_ACTIVATE to prevent post-hash schema injection handle_eip712_filtering() under P2_FILT_ACTIVATE computes the schema hash that downstream filter signatures are issued against, but left the EIP-712 type system unlocked: the host could continue sending INS_EIP712_STRUCT_DEF APDUs after the activate, append fields or even entire structs to the schema, and then sign a typed message whose actual schema differs from the one the filter metadata was issued for. Compute the schema hash first, and only on success switch the UI into filtering-full mode and set struct_state to DEFINED so subsequent handle_eip712_struct_def() calls are refused by the existing gate at commands_712.c:94. The whole branch is inside the `!N_storage.verbose_eip712` check (verbose mode never computes the hash). All three state changes (hash, filtering mode, type-system lock) move together, so a transient compute_schema_hash() failure leaves the handle clean and the host can retry the activate. Co-Authored-By: Claude Opus 4.7 --- src/features/sign_message_eip712/commands_712.c | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/src/features/sign_message_eip712/commands_712.c b/src/features/sign_message_eip712/commands_712.c index 031ac6cba..2d4ec9666 100644 --- a/src/features/sign_message_eip712/commands_712.c +++ b/src/features/sign_message_eip712/commands_712.c @@ -194,8 +194,17 @@ uint16_t handle_eip712_filtering(uint8_t p1, uint8_t p2, const uint8_t *cdata, u switch (p2) { case P2_FILT_ACTIVATE: if (!N_storage.verbose_eip712) { - ui_712_set_filtering_mode(EIP712_FILTERING_FULL); ret = compute_schema_hash(); + if (ret) { + // Switch to filtering mode and lock the type system in + // one atomic step: a host cannot append struct + // definitions after the hash is fixed and so cannot sign + // a message whose schema differs from the one the hash + // covered. On hash-compute failure, both state changes + // are skipped so the activate can be retried. + ui_712_set_filtering_mode(EIP712_FILTERING_FULL); + struct_state = DEFINED; + } } forget_known_assets(); break; From cff26819340e573e20270dbb9b49483cbeed9c43 Mon Sep 17 00:00:00 2001 From: Charles-Edouard de la Vergne Date: Wed, 13 May 2026 09:44:34 +0200 Subject: [PATCH 26/29] fix: Strip uint256 zero padding before rendering EIP-712 datetime values MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ui_712_format_datetime() decoded the timestamp with u64_from_BE(data, length), which reads at most 8 bytes from the start of the buffer. EIP-712 typically declares timestamps as uint256, so a host-supplied 32-byte value carries its trailing 8 bytes as the meaningful payload and zero-pads the first 24. The formatter therefore read 8 bytes of padding, displayed 1970-01-01, and let the user sign a hash computed over the actual timestamp. Detect that the buffer is wider than uint64_t, verify the leading bytes are zero, and advance the data pointer past the padding so the decoded timestamp matches what is being hashed. Non-zero leading bytes mean the value cannot fit a time_t — refuse the screen in that case rather than wrap to an arbitrary date. Co-Authored-By: Claude Opus 4.7 --- src/features/sign_message_eip712/ui_logic.c | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/src/features/sign_message_eip712/ui_logic.c b/src/features/sign_message_eip712/ui_logic.c index 34cd117e1..f09b06a8e 100644 --- a/src/features/sign_message_eip712/ui_logic.c +++ b/src/features/sign_message_eip712/ui_logic.c @@ -639,6 +639,22 @@ static bool ui_712_format_datetime(const uint8_t *data, snprintf(strings.tmp.tmp, sizeof(strings.tmp.tmp), "Unlimited"); return true; } + // u64_from_BE() reads from the front of the buffer; for a wide EIP-712 + // type (e.g. uint256), the trailing 8 bytes carry the value and the + // leading bytes are zero-padding. Strip the padding before decoding so + // the displayed timestamp matches what is being hashed, and refuse the + // value entirely if it doesn't fit in a uint64. + if (length > sizeof(uint64_t)) { + uint8_t leading = length - sizeof(uint64_t); + for (uint8_t i = 0; i < leading; ++i) { + if (data[i] != 0) { + PRINTF("Datetime value too large for time_t\n"); + return false; + } + } + data += leading; + length = sizeof(uint64_t); + } timestamp = u64_from_BE(data, length); return time_format_to_utc(×tamp, strings.tmp.tmp, sizeof(strings.tmp.tmp)); } From 018b5c5dd6d38066b8f6197aa00269d8691fb582 Mon Sep 17 00:00:00 2001 From: Charles-Edouard de la Vergne Date: Wed, 13 May 2026 09:46:37 +0200 Subject: [PATCH 27/29] fix: Zero ERC-20 plugin context and require both ABI fields before review The ERC-20 internal plugin only cleared `extra_data` at ETH_PLUGIN_INIT_CONTRACT, leaving `destinationAddress`, `amount`, `ticker`, `decimals`, `contract_name`, and `selectorIndex` from the previous signing flow alive in the per-plugin global context that backs dataContext.tokenContext.pluginContext. A host that started a new transfer with selector-compatible but malformed calldata (wrong ABI offsets, truncated payload) could then reach ETH_PLUGIN_FINALIZE with neither the destination nor the amount parameter actually observed, and the trusted review screen would display the stale values from the previous flow as if they were the current ones. Zero the entire context at INIT and add `destination_parsed` / `amount_parsed` flags that the parameter handlers flip when the two mandatory ABI offsets fire. FINALIZE refuses the screen if either flag is missing, so non-conforming calldata is reported as ERROR instead of rendering stale state. Co-Authored-By: Claude Opus 4.7 --- src/plugins/erc20/erc20_plugin.c | 22 ++++++++++++++++++++-- 1 file changed, 20 insertions(+), 2 deletions(-) diff --git a/src/plugins/erc20/erc20_plugin.c b/src/plugins/erc20/erc20_plugin.c index 763cddd9f..3e826fc9b 100644 --- a/src/plugins/erc20/erc20_plugin.c +++ b/src/plugins/erc20/erc20_plugin.c @@ -31,6 +31,8 @@ typedef struct erc20_parameters_t { // data not part of the ABI (usually for tracking purposes) char extra_data[MAX_EXTRA_DATA_CHUNKS * CALLDATA_CHUNK_SIZE]; uint8_t extra_data_len; + bool destination_parsed; + bool amount_parsed; } erc20_parameters_t; void erc20_plugin_call(eth_plugin_msg_t message, void *parameters) { @@ -39,8 +41,10 @@ void erc20_plugin_call(eth_plugin_msg_t message, void *parameters) { ethPluginInitContract_t *msg = (ethPluginInitContract_t *) parameters; erc20_parameters_t *context = (erc20_parameters_t *) msg->pluginContext; - explicit_bzero(context->extra_data, sizeof(context->extra_data)); - context->extra_data_len = 0; + // Zero the entire context so a stale destinationAddress/amount/ + // ticker/decimals from a previous signing flow cannot bleed into + // the review screen if the next calldata fails to populate them. + explicit_bzero(context, sizeof(*context)); // enforce that ETH amount should be 0 if (!is_zeroes_buffer(msg->txContent->value.value, CALLDATA_CHUNK_SIZE)) { @@ -82,6 +86,7 @@ void erc20_plugin_call(eth_plugin_msg_t message, void *parameters) { memmove(context->destinationAddress, msg->parameter + (CALLDATA_CHUNK_SIZE - ADDRESS_LENGTH), ADDRESS_LENGTH); + context->destination_parsed = true; msg->result = ETH_PLUGIN_RESULT_OK; break; @@ -91,6 +96,7 @@ void erc20_plugin_call(eth_plugin_msg_t message, void *parameters) { // ^^^^^^^^^^^^^^ case CALLDATA_SELECTOR_SIZE + CALLDATA_CHUNK_SIZE: memmove(context->amount, msg->parameter, CALLDATA_CHUNK_SIZE); + context->amount_parsed = true; msg->result = ETH_PLUGIN_RESULT_OK; break; @@ -124,6 +130,18 @@ void erc20_plugin_call(eth_plugin_msg_t message, void *parameters) { ethPluginFinalize_t *msg = (ethPluginFinalize_t *) parameters; erc20_parameters_t *context = (erc20_parameters_t *) msg->pluginContext; PRINTF("erc20 plugin finalize %u\n", pluginType); + // Refuse to render the review screen unless both mandatory ABI + // parameters were observed; without this, malformed calldata + // (wrong offsets, truncated payload) would let the contextual + // zeros land on screen as a legitimate-looking "transfer 0 to + // 0x000...0000" prompt. + if (!context->destination_parsed || !context->amount_parsed) { + PRINTF("erc20: missing mandatory parameter (dest=%d, amount=%d)\n", + context->destination_parsed, + context->amount_parsed); + msg->result = ETH_PLUGIN_RESULT_ERROR; + break; + } msg->tokenLookup1 = msg->txContent->destination; msg->numScreens = 2; if (context->extra_data_len > 0) { From e59e5c9d9042299591a1396b0f992857f7198b34 Mon Sep 17 00:00:00 2001 From: Charles-Edouard de la Vergne Date: Wed, 13 May 2026 10:00:41 +0200 Subject: [PATCH 28/29] fix: Validate P1/P2 explicitly in INS_PROVIDE_MAP_ENTRY handler MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit handle_map_entry() compared P1 to P1_FIRST_CHUNK to decide whether to reset the TLV state, but any other P1 value silently fell into the "following chunk" branch — including reserved/unknown values that should be rejected. P2 was explicitly discarded via `(void) p2;` and any non-zero P2 was accepted as well. Reject P1 values that are neither P1_FIRST_CHUNK nor P1_FOLLOWING_CHUNK, and reject any non-zero P2. Returns SWO_WRONG_P1_P2 in both cases, matching the convention used by the other multi-chunk handlers (privacy_operation, sign_tx, safe_account, eth2_withdrawal_index, network_icon). Co-Authored-By: Claude Opus 4.7 --- src/features/provide_map_entry/cmd_map_entry.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/src/features/provide_map_entry/cmd_map_entry.c b/src/features/provide_map_entry/cmd_map_entry.c index 7d8918778..3ca7520e2 100644 --- a/src/features/provide_map_entry/cmd_map_entry.c +++ b/src/features/provide_map_entry/cmd_map_entry.c @@ -12,7 +12,12 @@ static bool handle_tlv_payload(const buffer_t *buf) { } uint16_t handle_map_entry(uint8_t p1, uint8_t p2, uint8_t lc, const uint8_t *payload) { - (void) p2; + if ((p1 != P1_FIRST_CHUNK) && (p1 != P1_FOLLOWING_CHUNK)) { + return SWO_WRONG_P1_P2; + } + if (p2 != 0) { + return SWO_WRONG_P1_P2; + } if (!tlv_from_apdu(p1 == P1_FIRST_CHUNK, lc, payload, &handle_tlv_payload)) { return SWO_INCORRECT_DATA; } From 1dbb360d670e703e1c6339e1dd2d51fc46a6d88f Mon Sep 17 00:00:00 2001 From: Charles-Edouard de la Vergne Date: Wed, 13 May 2026 12:13:14 +0200 Subject: [PATCH 29/29] ci: Replace ad-m/github-push-action@master with native git push The plugin-SDK auto-bump workflow used ad-m/github-push-action pinned to the upstream master branch. That is a textbook CWE-829: a supply-chain compromise of the action's master would inject arbitrary shell into every Ethereum-plugin auto-PR run, with write access to every LedgerHQ/app-plugin-* repository through the CI bot token. Pinning to a SHA would reduce but not remove that risk. Instead, replace the action with the same `git remote set-url` + `git push` pattern already used by ledger-app-workflows' _open_pr_with_new_snapshots.yml. The push step now runs only the shell visible in this file and uses the same CI_BOT_TOKEN as before. Co-Authored-By: Claude Opus 4.7 --- .github/workflows/pr_on_all_plugins.yml | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/.github/workflows/pr_on_all_plugins.yml b/.github/workflows/pr_on_all_plugins.yml index f2b2ad94d..9bc28b170 100644 --- a/.github/workflows/pr_on_all_plugins.yml +++ b/.github/workflows/pr_on_all_plugins.yml @@ -126,18 +126,21 @@ jobs: echo "Branch Name: $branch_name" echo "Title: $title" git status + git checkout -b "$branch_name" git commit -am "$title" # Set output echo "title=$title" >> $GITHUB_OUTPUT echo "branch_name=$branch_name" >> $GITHUB_OUTPUT - name: Push commit - uses: ad-m/github-push-action@master - with: - github_token: ${{ secrets.CI_BOT_TOKEN }} - branch: ${{ steps.commit-changes.outputs.branch_name }} - repository: LedgerHQ/${{ matrix.repo }} - force: true + env: + GH_TOKEN: ${{ secrets.CI_BOT_TOKEN }} + run: | + # Push the branch via the CI bot token. + branch_name="${{ steps.commit-changes.outputs.branch_name }}" + git remote set-url origin \ + "https://x-access-token:${GH_TOKEN}@github.com/LedgerHQ/${{ matrix.repo }}.git" + git push -u origin "$branch_name" --force - name: Create 'auto' label if missing run: |