Skip to content

Commit 48feae3

Browse files
committed
gui: fix cJSON_Parse overrun
1 parent 6162f2e commit 48feae3

File tree

5 files changed

+25
-22
lines changed

5 files changed

+25
-22
lines changed

src/app/firedancer/topology.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -428,7 +428,7 @@ fd_topo_initialize( config_t * config ) {
428428
/**/ fd_topob_link( topo, "snapct_repr", "snapct_repr", 128UL, 0UL, 1UL )->permit_no_consumers = 1; /* TODO: wire in repair later */
429429
if( FD_LIKELY( config->tiles.gui.enabled ) ) {
430430
/**/ fd_topob_link( topo, "snapct_gui", "snapct_gui", 128UL, sizeof(fd_snapct_update_t), 1UL );
431-
/**/ fd_topob_link( topo, "snapin_gui", "snapin_gui", 128UL, FD_GUI_CONFIG_PARSE_MAX_VALID_ACCT_SZ, 1UL );
431+
/**/ fd_topob_link( topo, "snapin_gui", "snapin_gui", 128UL, FD_GUI_CONFIG_PARSE_MAX_VALID_ACCT_SZ_WITH_NULL, 1UL );
432432
}
433433
if( vinyl_enabled ) {
434434
fd_topo_link_t * snapin_wh =

src/disco/gui/fd_gui_config_parse.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -66,7 +66,7 @@ fd_gui_config_parse_validator_info_check( uchar const * data,
6666

6767
CHECK_LEFT( sizeof(ulong) ); ulong json_str_sz = FD_LOAD( ulong, data+i ); i += sizeof(ulong);
6868

69-
CHECK_LEFT( json_str_sz );
69+
CHECK_LEFT( json_str_sz+1UL ); /* cJSON_ParseWithLengthOpts requires having byte after the JSON payload */
7070
cJSON * json = cJSON_ParseWithLengthOpts( (char *)(data+i), json_str_sz, NULL, 0 );
7171
if( FD_UNLIKELY( !json ) ) return 0;
7272

src/disco/gui/fd_gui_config_parse.h

Lines changed: 8 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -6,13 +6,14 @@
66
#include "../../util/fd_util_base.h"
77

88
/* https://github.com/anza-xyz/agave/blob/master/account-decoder/src/validator_info.rs */
9-
#define FD_GUI_CONFIG_PARSE_VALIDATOR_INFO_NAME_SZ ( 80UL) /* +1UL for NULL terminator */
10-
#define FD_GUI_CONFIG_PARSE_VALIDATOR_INFO_WEBSITE_SZ ( 80UL)
11-
#define FD_GUI_CONFIG_PARSE_VALIDATOR_INFO_DETAILS_SZ ( 300UL)
12-
#define FD_GUI_CONFIG_PARSE_VALIDATOR_INFO_ICON_URI_SZ ( 80UL)
13-
#define FD_GUI_CONFIG_PARSE_VALIDATOR_INFO_KEYBASE_USERNAME_SZ (80UL)
14-
#define FD_GUI_CONFIG_PARSE_VALIDATOR_INFO_MAX_SZ ( 576UL) /* does not include size of ConfigKeys */
15-
#define FD_GUI_CONFIG_PARSE_MAX_VALID_ACCT_SZ (FD_GUI_CONFIG_PARSE_CONFIG_KEYS_MAX_SZ+FD_GUI_CONFIG_PARSE_VALIDATOR_INFO_MAX_SZ)
9+
#define FD_GUI_CONFIG_PARSE_VALIDATOR_INFO_NAME_SZ ( 80UL) /* +1UL for NULL terminator */
10+
#define FD_GUI_CONFIG_PARSE_VALIDATOR_INFO_WEBSITE_SZ ( 80UL)
11+
#define FD_GUI_CONFIG_PARSE_VALIDATOR_INFO_DETAILS_SZ ( 300UL)
12+
#define FD_GUI_CONFIG_PARSE_VALIDATOR_INFO_ICON_URI_SZ ( 80UL)
13+
#define FD_GUI_CONFIG_PARSE_VALIDATOR_INFO_KEYBASE_USERNAME_SZ ( 80UL)
14+
#define FD_GUI_CONFIG_PARSE_VALIDATOR_INFO_MAX_SZ ( 576UL) /* does not include size of ConfigKeys */
15+
#define FD_GUI_CONFIG_PARSE_MAX_VALID_ACCT_SZ (FD_GUI_CONFIG_PARSE_CONFIG_KEYS_MAX_SZ+FD_GUI_CONFIG_PARSE_VALIDATOR_INFO_MAX_SZ)
16+
#define FD_GUI_CONFIG_PARSE_MAX_VALID_ACCT_SZ_WITH_NULL (FD_GUI_CONFIG_PARSE_MAX_VALID_ACCT_SZ+1UL) /* cJSON parser requires one byte past the parsable JSON */
1617

1718
/* The size of a ConfigKeys of length 2, which is the expected length of ValidatorInfo */
1819
#define FD_GUI_CONFIG_PARSE_CONFIG_KEYS_MAX_SZ (1UL + (32UL + 1UL)*2UL)

src/disco/gui/fuzz_config_parser.c

Lines changed: 5 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -27,17 +27,16 @@ LLVMFuzzerTestOneInput( uchar const * data,
2727
cJSON * json;
2828
fd_gui_config_parse_info_t validator_info[1];
2929
fd_pubkey_t pubkey;
30-
FD_LOG_WARNING(("TEST"));
3130
int valid = fd_gui_config_parse_validator_info_check( data, size, &json, &pubkey );
3231

3332
if( valid ) {
3433
fd_gui_config_parse_validator_info( json, validator_info );
3534

36-
assert( fd_utf8_verify( validator_info->name, strlen( validator_info->name ) ) );
37-
assert( fd_utf8_verify( validator_info->website, strlen( validator_info->name ) ) );
38-
assert( fd_utf8_verify( validator_info->details, strlen( validator_info->name ) ) );
39-
assert( fd_utf8_verify( validator_info->icon_uri, strlen( validator_info->name ) ) );
40-
assert( fd_utf8_verify( validator_info->keybase_username, strlen( validator_info->name ) ) );
35+
assert( fd_utf8_verify( validator_info->name, strlen( validator_info->name ) ) );
36+
assert( fd_utf8_verify( validator_info->website, strlen( validator_info->website ) ) );
37+
assert( fd_utf8_verify( validator_info->details, strlen( validator_info->details ) ) );
38+
assert( fd_utf8_verify( validator_info->icon_uri, strlen( validator_info->icon_uri ) ) );
39+
assert( fd_utf8_verify( validator_info->keybase_username, strlen( validator_info->keybase_username ) ) );
4140
}
4241
return 0;
4342
}

src/discof/restore/fd_snapin_tile.c

Lines changed: 10 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -519,16 +519,19 @@ handle_data_frag( fd_snapin_tile_t * ctx,
519519

520520
/* We exepect ConfigKeys Vec to be length 2. We expect the size
521521
of ConfigProgram-owned accounts to be
522-
FD_GUI_CONFIG_PARSE_MAX_VALID_ACCT_SZ, since this the the
523-
size that the solana CLI allocates for them. Although the
524-
Config program itself does not enforce this limit, the vast
525-
majority of accounts (with a tiny number of excpetions on
526-
devnet) are maintained with the solana cli. */
522+
FD_GUI_CONFIG_PARSE_MAX_VALID_ACCT_SZ, since this the size
523+
that the solana CLI allocates for them. Although the Config
524+
program itself does not enforce this limit, the vast majority
525+
of accounts (with a tiny number of excpetions on devnet) are
526+
maintained with the solana cli. */
527527
if( FD_UNLIKELY( ctx->gui_out.idx!=ULONG_MAX && !memcmp( result->account_data.owner, fd_solana_config_program_id.key, sizeof(fd_hash_t) ) && result->account_data.data_sz && *(uchar *)result->account_data.data==2UL && result->account_data.data_sz<=FD_GUI_CONFIG_PARSE_MAX_VALID_ACCT_SZ ) ) {
528528
uchar * acct = fd_chunk_to_laddr( ctx->gui_out.mem, ctx->gui_out.chunk );
529529
fd_memcpy( acct, result->account_data.data, result->account_data.data_sz );
530-
fd_stem_publish( stem, ctx->gui_out.idx, 0UL, ctx->gui_out.chunk, result->account_data.data_sz, 0UL, 0UL, 0UL );
531-
ctx->gui_out.chunk = fd_dcache_compact_next( ctx->gui_out.chunk, result->account_data.data_sz, ctx->gui_out.chunk0, ctx->gui_out.wmark );
530+
531+
/* We add 1 to the frag size since the cJSON parser used by
532+
the gui tile requires one byte past the parsable JSON */
533+
fd_stem_publish( stem, ctx->gui_out.idx, 0UL, ctx->gui_out.chunk, result->account_data.data_sz+1UL, 0UL, 0UL, 0UL );
534+
ctx->gui_out.chunk = fd_dcache_compact_next( ctx->gui_out.chunk, result->account_data.data_sz+1UL, ctx->gui_out.chunk0, ctx->gui_out.wmark );
532535
}
533536
break;
534537
case FD_SSPARSE_ADVANCE_ACCOUNT_BATCH:

0 commit comments

Comments
 (0)