diff --git a/app/Makefile.version b/app/Makefile.version index 835d0ee0..979a4dde 100644 --- a/app/Makefile.version +++ b/app/Makefile.version @@ -3,4 +3,4 @@ APPVERSION_M=2 # This is the `spec_version` field of `Runtime` APPVERSION_N=35 # This is the patch version of this release -APPVERSION_P=25 +APPVERSION_P=26 diff --git a/app/src/common/parser_common.h b/app/src/common/parser_common.h index 95e8f9be..bd437a66 100644 --- a/app/src/common/parser_common.h +++ b/app/src/common/parser_common.h @@ -22,6 +22,14 @@ extern "C" { #include #include +#if defined(TARGET_NANOS2) || defined(TARGET_STAX) || defined(TARGET_FLEX) +#define TX_BUFFER_SIZE 16384 +#elif defined(TARGET_NANOX) +#define TX_BUFFER_SIZE 16384 +#elif defined(TARGET_NANOS) +#define TX_BUFFER_SIZE 8192 +#endif + #define CHECK_PARSER_ERR(__CALL) { \ parser_error_t __err = __CALL; \ CHECK_APP_CANARY() \ diff --git a/app/src/json/json_parser.c b/app/src/json/json_parser.c index e7adf3f5..cc6741f1 100644 --- a/app/src/json/json_parser.c +++ b/app/src/json/json_parser.c @@ -22,6 +22,14 @@ #define EQUALS(_P, _Q, _LEN) (MEMCMP( (const void*) PIC(_P), (const void*) PIC(_Q), (_LEN))==0) parser_error_t json_parse(parsed_json_t *parsed_json, const char *buffer, uint16_t bufferLen) { + // This check was previously implemented to prevent, here we want to avoid false positives. + // It is especially important in fuzzing environments where this check was omitted. +#if defined(TARGET_NANOS) || defined(TARGET_NANOS2) || defined(TARGET_NANOX) || defined(TARGET_STAX) || defined(TARGET_FLEX) + if (bufferLen > TX_BUFFER_SIZE) { + return parser_context_unexpected_size; + } +#endif + jsmn_parser parser; jsmn_init(&parser); diff --git a/app/src/tx_validate.c b/app/src/tx_validate.c index b3956706..057530d3 100644 --- a/app/src/tx_validate.c +++ b/app/src/tx_validate.c @@ -37,7 +37,7 @@ int8_t is_space(char c) { return 0; } -int8_t contains_whitespace(parsed_json_t *json) { +parser_error_t contains_whitespace(parsed_json_t *json) { int start = 0; const int last_element_index = json->tokens[0].end; @@ -47,21 +47,26 @@ int8_t contains_whitespace(parsed_json_t *json) { const int end = json->tokens[i].start; for (int j = start; j < end; j++) { if (is_space(json->buffer[j]) == 1) { - return 1; + return parser_json_contains_whitespace; } } start = json->tokens[i].end + 1; } else { - return 0; + return parser_ok; } } + + if (start < 0) { + return parser_json_unexpected_error; + } + while (start < last_element_index && json->buffer[start] != '\0') { if (is_space(json->buffer[start])) { - return 1; + return parser_json_contains_whitespace; } start++; } - return 0; + return parser_ok; } int8_t is_sorted(uint16_t first_index, @@ -128,8 +133,9 @@ int8_t dictionaries_sorted(parsed_json_t *json) { } parser_error_t tx_validate(parsed_json_t *json) { - if (contains_whitespace(json) == 1) { - return parser_json_contains_whitespace; + parser_error_t err = contains_whitespace(json); + if (err != parser_ok) { + return err; } if (dictionaries_sorted(json) != 1) { @@ -137,7 +143,6 @@ parser_error_t tx_validate(parsed_json_t *json) { } uint16_t token_index; - parser_error_t err; err = object_get_value(json, 0, "chain_id", &token_index); if (err != parser_ok)