Skip to content

Commit 75ae28f

Browse files
committed
gossip: sanitizers for published types (lowest_slot, vote, duplicate_shred, snapshot_hashes)
1 parent a198ea6 commit 75ae28f

File tree

2 files changed

+36
-1
lines changed

2 files changed

+36
-1
lines changed

src/flamenco/gossip/fd_gossip_msg_parse.c

Lines changed: 34 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,17 @@
33

44
/* https://github.com/anza-xyz/agave/blob/bff4df9cf6f41520a26c9838ee3d4d8c024a96a1/gossip/src/crds_data.rs#L22-L23 */
55
#define WALLCLOCK_MAX_MILLIS (1000000000000000UL)
6+
#define MAX_SLOT (1000000000000000UL)
7+
8+
/* https://github.com/anza-xyz/agave/blob/master/gossip/src/epoch_slots.rs#L15 */
9+
#define MAX_SLOTS_PER_EPOCH_SLOT (2048UL*8UL)
10+
11+
struct __attribute__((packed)) slot_hash_pair {
12+
ulong slot;
13+
uchar hash[ 32UL ];
14+
};
15+
16+
typedef struct slot_hash_pair slot_hash_pair_t;
617

718
/* Adapted from fd_txn_parse.c */
819
#define CHECK_INIT( payload, payload_sz, offset ) \
@@ -162,6 +173,8 @@ fd_gossip_msg_crds_vote_parse( fd_gossip_view_crds_value_t * crds_val,
162173
ulong start_offset ) {
163174
CHECK_INIT( payload, payload_sz, start_offset );
164175
CHECK_LEFT( 1U ); crds_val->vote->index = FD_LOAD( uchar, CURSOR ) ; INC( 1U );
176+
/* https://github.com/anza-xyz/agave/blob/bff4df9cf6f41520a26c9838ee3d4d8c024a96a1/gossip/src/crds_data.rs#L67-L107 */
177+
CHECK( crds_val->vote->index<FD_GOSSIP_VOTE_IDX_MAX );
165178
CHECK_LEFT( 32U ); crds_val->pubkey_off = CUR_OFFSET ; INC( 32U );
166179
ulong transaction_sz;
167180
CHECK( fd_txn_parse_core( CURSOR, BYTES_REMAINING, NULL, NULL, &transaction_sz )!=0UL );
@@ -178,7 +191,10 @@ fd_gossip_msg_crds_lowest_slot_parse( fd_gossip_view_crds_value_t * crds_val,
178191
ulong payload_sz,
179192
ulong start_offset ) {
180193
CHECK_INIT( payload, payload_sz, start_offset );
181-
CHECKED_INC( 1U ); /* deprecated */
194+
CHECK_LEFT( 1U ); uchar ix = FD_LOAD( uchar, CURSOR ) ; INC( 1U );
195+
/* https://github.com/anza-xyz/agave/blob/bff4df9cf6f41520a26c9838ee3d4d8c024a96a1/gossip/src/crds_data.rs#L67-L107 */
196+
CHECK( !ix );
197+
182198
CHECK_LEFT( 32U ); crds_val->pubkey_off = CUR_OFFSET ; INC( 32U );
183199

184200
CHECKED_INC( 8U ); /* root: deprecated */
@@ -295,12 +311,16 @@ fd_gossip_msg_crds_duplicate_shred_parse( fd_gossip_view_crds_value_t * crds_val
295311
CHECK_INIT( payload, payload_sz, start_offset );
296312

297313
CHECK_LEFT( 2U ); ds->index = FD_LOAD( ushort, CURSOR ) ; INC( 2U );
314+
/* https://github.com/anza-xyz/agave/blob/bff4df9cf6f41520a26c9838ee3d4d8c024a96a1/gossip/src/crds_data.rs#L67-L107 */
315+
CHECK( ds->index<FD_GOSSIP_DUPLICATE_SHRED_IDX_MAX );
298316
CHECK_LEFT( 32U ); crds_val->pubkey_off = CUR_OFFSET ; INC( 32U );
299317
CHECKED_WALLCLOCK_LOAD( crds_val->wallclock_nanos );
300318
CHECK_LEFT( 8U ); ds->slot = FD_LOAD( ulong, CURSOR ) ; INC( 8U );
301319
CHECKED_INC( 4U+1U ); /* (unused) + shred type (unused) */
302320
CHECK_LEFT( 1U ); ds->num_chunks = FD_LOAD( uchar, CURSOR ) ; INC( 1U );
303321
CHECK_LEFT( 1U ); ds->chunk_index = FD_LOAD( uchar, CURSOR ) ; INC( 1U );
322+
/* https://github.com/anza-xyz/agave/blob/bff4df9cf6f41520a26c9838ee3d4d8c024a96a1/gossip/src/duplicate_shred.rs#L328-L336 */
323+
CHECK( ds->chunk_index<ds->num_chunks );
304324
CHECK_LEFT( 8U ); ds->chunk_len = FD_LOAD( ulong, CURSOR ) ; INC( 8U );
305325
CHECK_LEFT( ds->chunk_len ); ds->chunk_off = CUR_OFFSET ; INC( ds->chunk_len );
306326
return BYTES_CONSUMED;
@@ -315,9 +335,22 @@ fd_gossip_msg_crds_snapshot_hashes_parse( fd_gossip_view_crds_value_t * crds_val
315335
CHECK_LEFT( 32U ); crds_val->pubkey_off = CUR_OFFSET ; INC( 32U );
316336
CHECK_LEFT( 40U ); crds_val->snapshot_hashes->full_off = CUR_OFFSET ; INC( 40U );
317337
CHECK_LEFT( 8U ); ulong incremental_len = FD_LOAD( ulong, CURSOR ) ; INC( 8U );
338+
CHECK( incremental_len<(ULONG_MAX-39U)/40U ); /* to prevent overflow in next check */
318339
CHECK_LEFT( incremental_len*40U ); crds_val->snapshot_hashes->inc_off = CUR_OFFSET ; INC( incremental_len*40U );
319340
CHECKED_WALLCLOCK_LOAD( crds_val->wallclock_nanos );
320341
crds_val->snapshot_hashes->inc_len = incremental_len;
342+
343+
/* https://github.com/anza-xyz/agave/blob/bff4df9cf6f41520a26c9838ee3d4d8c024a96a1/gossip/src/crds_data.rs#L265-L282 */
344+
slot_hash_pair_t * full_pair = (slot_hash_pair_t *)(payload + crds_val->snapshot_hashes->full_off);
345+
ulong full_slot = full_pair->slot;
346+
CHECK( full_slot<MAX_SLOT );
347+
348+
slot_hash_pair_t * inc_pair = (slot_hash_pair_t *)(payload + crds_val->snapshot_hashes->inc_off);
349+
for( ulong i=0UL; i<incremental_len; i++ ) {
350+
CHECK( inc_pair[i].slot>full_slot );
351+
CHECK( inc_pair[i].slot<MAX_SLOT );
352+
}
353+
321354
return BYTES_CONSUMED;
322355
}
323356

src/flamenco/gossip/fd_gossip_private.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -183,6 +183,7 @@ struct fd_gossip_view_node_instance {
183183

184184
typedef struct fd_gossip_view_node_instance fd_gossip_view_node_instance_t;
185185

186+
#define FD_GOSSIP_VOTE_IDX_MAX (32U)
186187
struct fd_gossip_view_vote {
187188
uchar index;
188189
ulong txn_sz;
@@ -197,6 +198,7 @@ struct fd_gossip_view_epoch_slots {
197198

198199
typedef struct fd_gossip_view_epoch_slots fd_gossip_view_epoch_slots_t;
199200

201+
#define FD_GOSSIP_DUPLICATE_SHRED_IDX_MAX (512U)
200202
struct fd_gossip_view_duplicate_shred {
201203
ushort index;
202204
ulong slot;

0 commit comments

Comments
 (0)