@@ -286,7 +286,12 @@ static uint8_t tlv_array_append_tlv_new(tlv_array_t *tlv_array, uint8_t type, ui
286286
287287static uint8_t tlv_array_append_tlv_new_usascii (tlv_array_t * tlv_array , uint8_t type , uint16_t length , const void * value )
288288{
289- pp2_tlv_t * tlv = tlv_new (type , length + 1 , value );
289+ pp2_tlv_t * tlv ;
290+ if (length == UINT16_MAX )
291+ {
292+ return 0 ;
293+ }
294+ tlv = tlv_new (type , length + 1 , value );
290295 if (!tlv )
291296 {
292297 return 0 ;
@@ -409,20 +414,42 @@ uint8_t pp_info_add_ssl(pp_info_t *pp_info, const char *version, const char *cip
409414
410415uint8_t pp_info_add_netns (pp_info_t * pp_info , const char * netns )
411416{
412- return tlv_array_append_tlv_new (& pp_info -> pp2_info .tlv_array , PP2_TYPE_NETNS , (uint16_t ) strlen (netns ), netns );
417+ size_t netns_len ;
418+ if (!netns )
419+ {
420+ return 0 ;
421+ }
422+ netns_len = strlen (netns );
423+ if (netns_len > UINT16_MAX )
424+ {
425+ return 0 ;
426+ }
427+ return tlv_array_append_tlv_new (& pp_info -> pp2_info .tlv_array , PP2_TYPE_NETNS , (uint16_t ) netns_len , netns );
413428}
414429
415430uint8_t pp_info_add_aws_vpce_id (pp_info_t * pp_info , const char * vpce_id )
416431{
417- uint16_t length = sizeof_pp2_tlv_aws_t + (uint16_t ) strlen (vpce_id );
418- pp2_tlv_aws_t * pp2_tlv_aws = malloc (length );
432+ size_t vpce_id_len ;
433+ uint16_t length ;
434+ pp2_tlv_aws_t * pp2_tlv_aws ;
419435 uint8_t rc ;
436+ if (!vpce_id )
437+ {
438+ return 0 ;
439+ }
440+ vpce_id_len = strlen (vpce_id );
441+ if (vpce_id_len > UINT16_MAX - sizeof_pp2_tlv_aws_t )
442+ {
443+ return 0 ;
444+ }
445+ length = (uint16_t )(sizeof_pp2_tlv_aws_t + vpce_id_len );
446+ pp2_tlv_aws = malloc (length );
420447 if (!pp2_tlv_aws )
421448 {
422449 return 0 ;
423450 }
424451 pp2_tlv_aws -> type = PP2_SUBTYPE_AWS_VPCE_ID ;
425- memcpy (pp2_tlv_aws -> value , vpce_id , strlen ( vpce_id ) );
452+ memcpy (pp2_tlv_aws -> value , vpce_id , vpce_id_len );
426453 rc = tlv_array_append_tlv_new (& pp_info -> pp2_info .tlv_array , PP2_TYPE_AWS , length , pp2_tlv_aws );
427454 free (pp2_tlv_aws );
428455 return rc ;
@@ -795,7 +822,7 @@ static uint8_t *pp2_create_hdr(const pp_info_t *pp_info, uint16_t *pp2_hdr_len,
795822 memcpy (pp2_hdr + index , tlv_array -> tlvs [i ], tlv_len );
796823 index += tlv_len ;
797824 }
798- if (pp_info -> pp2_info .alignment_power > 1 )
825+ if (pp_info -> pp2_info .alignment_power > 1 && padding_bytes > 0 )
799826 {
800827 pp2_tlv_t tlv = { 0 };
801828 tlv .type = PP2_TYPE_NOOP ;
@@ -1055,12 +1082,12 @@ static int32_t pp2_parse_hdr(const uint8_t *buffer, uint32_t buffer_length, pp_i
10551082 }
10561083
10571084 /* TLVs */
1058- /* Any TLV vector must be at least 3 bytes */
1059- while (tlv_vectors_len > sizeof_pp2_tlv_t )
1085+ /* Any TLV vector must be at least 3 bytes (sizeof_pp2_tlv_t) */
1086+ while (tlv_vectors_len >= sizeof_pp2_tlv_t )
10601087 {
10611088 const pp2_tlv_t * pp2_tlv = (const pp2_tlv_t * ) buffer ;
10621089 uint16_t pp2_tlv_len = pp2_tlv -> length_hi << 8 | pp2_tlv -> length_lo ;
1063- uint16_t pp2_tlv_offset = sizeof_pp2_tlv_t + pp2_tlv_len ;
1090+ uint32_t pp2_tlv_offset = ( uint32_t ) sizeof_pp2_tlv_t + pp2_tlv_len ;
10641091 if (pp2_tlv_offset > tlv_vectors_len )
10651092 {
10661093 return - ERR_PP2_TLV_LENGTH ;
@@ -1094,7 +1121,7 @@ static int32_t pp2_parse_hdr(const uint8_t *buffer, uint32_t buffer_length, pp_i
10941121 * Instead of zeroing the field in the buffer, compute CRC in 3 segments:
10951122 * before the checksum value, 4 zero bytes, after the checksum value. */
10961123 total_hdr_len = sizeof (proxy_hdr_v2_t ) + len ;
1097- offset_to_chksum_value = (const uint8_t * )pp2_tlv -> value - pp2_hdr ;
1124+ offset_to_chksum_value = (uint32_t )(( const uint8_t * )pp2_tlv -> value - pp2_hdr ) ;
10981125 after_chksum_offset = offset_to_chksum_value + sizeof (uint32_t );
10991126
11001127 crc = crc32c_continue (0xffffffff , pp2_hdr , offset_to_chksum_value );
@@ -1129,25 +1156,39 @@ static int32_t pp2_parse_hdr(const uint8_t *buffer, uint32_t buffer_length, pp_i
11291156 break ;
11301157 case PP2_TYPE_SSL :
11311158 {
1132- const pp2_tlv_ssl_t * pp2_tlv_ssl = ( const pp2_tlv_ssl_t * ) pp2_tlv -> value ;
1159+ const pp2_tlv_ssl_t * pp2_tlv_ssl ;
11331160 uint16_t pp2_tlvs_ssl_len = 0 , pp2_sub_tlv_offset = 0 ;
11341161 uint8_t tlv_ssl_version_found = 0 ;
11351162
1163+ if (pp2_tlv_len < sizeof (((pp2_tlv_ssl_t * )0 )-> client ) + sizeof (((pp2_tlv_ssl_t * )0 )-> verify ))
1164+ {
1165+ return - ERR_PP2_TYPE_SSL ;
1166+ }
1167+
1168+ pp2_tlv_ssl = (const pp2_tlv_ssl_t * ) pp2_tlv -> value ;
1169+
11361170 /* Set the pp2_ssl_info */
11371171 pp_info -> pp2_info .pp2_ssl_info .ssl = !!(pp2_tlv_ssl -> client & PP2_CLIENT_SSL );
11381172 pp_info -> pp2_info .pp2_ssl_info .cert_in_connection = !!(pp2_tlv_ssl -> client & PP2_CLIENT_CERT_CONN );
11391173 pp_info -> pp2_info .pp2_ssl_info .cert_in_session = !!(pp2_tlv_ssl -> client & PP2_CLIENT_CERT_SESS );
11401174 pp_info -> pp2_info .pp2_ssl_info .cert_verified = !pp2_tlv_ssl -> verify ;
11411175
11421176 pp2_tlvs_ssl_len = pp2_tlv_len - sizeof (pp2_tlv_ssl -> client ) - sizeof (pp2_tlv_ssl -> verify );
1143- while (pp2_sub_tlv_offset < pp2_tlvs_ssl_len )
1177+ while (pp2_sub_tlv_offset + sizeof_pp2_tlv_t <= pp2_tlvs_ssl_len )
11441178 {
11451179 const pp2_tlv_t * pp2_sub_tlv_ssl = (const pp2_tlv_t * ) ((const uint8_t * ) pp2_tlv_ssl -> sub_tlv + pp2_sub_tlv_offset );
11461180 uint16_t pp2_sub_tlv_ssl_len = pp2_sub_tlv_ssl -> length_hi << 8 | pp2_sub_tlv_ssl -> length_lo ;
1181+ if ((uint32_t ) sizeof_pp2_tlv_t + pp2_sub_tlv_ssl_len > (uint32_t )(pp2_tlvs_ssl_len - pp2_sub_tlv_offset ))
1182+ {
1183+ return - ERR_PP2_TYPE_SSL ;
1184+ }
1185+ if (pp2_sub_tlv_ssl -> type == PP2_SUBTYPE_SSL_VERSION )
1186+ {
1187+ tlv_ssl_version_found = 1 ;
1188+ }
11471189 switch (pp2_sub_tlv_ssl -> type )
11481190 {
11491191 case PP2_SUBTYPE_SSL_VERSION : /* US-ASCII */
1150- tlv_ssl_version_found = 1 ;
11511192 case PP2_SUBTYPE_SSL_CIPHER : /* US-ASCII */
11521193 case PP2_SUBTYPE_SSL_SIG_ALG : /* US-ASCII */
11531194 case PP2_SUBTYPE_SSL_KEY_ALG : /* US-ASCII */
@@ -1171,7 +1212,7 @@ static int32_t pp2_parse_hdr(const uint8_t *buffer, uint32_t buffer_length, pp_i
11711212
11721213 pp2_sub_tlv_offset += sizeof_pp2_tlv_t + pp2_sub_tlv_ssl_len ;
11731214 }
1174- if (pp2_sub_tlv_offset > pp2_tlvs_ssl_len || (pp_info -> pp2_info .pp2_ssl_info .ssl && !tlv_ssl_version_found ))
1215+ if (pp2_sub_tlv_offset != pp2_tlvs_ssl_len || (pp_info -> pp2_info .pp2_ssl_info .ssl && !tlv_ssl_version_found ))
11751216 {
11761217 return - ERR_PP2_TYPE_SSL ;
11771218 }
@@ -1247,15 +1288,15 @@ static int32_t pp1_parse_hdr(const uint8_t *buffer, uint32_t buffer_length, pp_i
12471288 char src_port_str [6 ] = { 0 };
12481289 char dst_port_str [6 ] = { 0 };
12491290
1250- memcpy (block , buffer , buffer_length < PP1_MAX_LENGTH ? buffer_length : PP1_MAX_LENGTH );
1291+ memcpy (block , buffer , buffer_length < PP1_MAX_LENGTH - 1 ? buffer_length : PP1_MAX_LENGTH - 1 );
12511292
12521293 block_end = strstr (block , CRLF );
12531294 if (!block_end )
12541295 {
12551296 return - ERR_PP1_CRLF ;
12561297 }
12571298 block_end += strlen (CRLF );
1258- pp1_hdr_len = block_end - block ;
1299+ pp1_hdr_len = ( int32_t )( block_end - block ) ;
12591300
12601301 /* PROXY */
12611302 if (memcmp (block , "PROXY" , 5 ))
@@ -1276,7 +1317,7 @@ static int32_t pp1_parse_hdr(const uint8_t *buffer, uint32_t buffer_length, pp_i
12761317 if (!inet_family )
12771318 {
12781319 /* Unknown connection (short form) */
1279- if (pp1_hdr_len == 15 || !memcmp (ptr , "UNKNOWN" , 7 ))
1320+ if (pp1_hdr_len == 15 && !memcmp (ptr , "UNKNOWN" , 7 ))
12801321 {
12811322 pp_info -> address_family = ADDR_FAMILY_UNSPEC ;
12821323 pp_info -> transport_protocol = TRANSPORT_PROTOCOL_UNSPEC ;
@@ -1323,7 +1364,7 @@ static int32_t pp1_parse_hdr(const uint8_t *buffer, uint32_t buffer_length, pp_i
13231364 {
13241365 return sa_family == AF_INET ? - ERR_PP1_IPV4_SRC_IP : - ERR_PP1_IPV6_SRC_IP ;
13251366 }
1326- src_address_length = src_address_end - ptr ;
1367+ src_address_length = ( uint16_t )( src_address_end - ptr ) ;
13271368 memcpy (pp_info -> src_addr , ptr , src_address_length );
13281369 if (inet_pton (sa_family , pp_info -> src_addr , & src_sin_addr ) != 1 )
13291370 {
@@ -1344,7 +1385,7 @@ static int32_t pp1_parse_hdr(const uint8_t *buffer, uint32_t buffer_length, pp_i
13441385 {
13451386 return sa_family == AF_INET ? - ERR_PP1_IPV4_DST_IP : - ERR_PP1_IPV6_DST_IP ;
13461387 }
1347- dst_address_length = dst_address_end - ptr ;
1388+ dst_address_length = ( uint16_t )( dst_address_end - ptr ) ;
13481389 memcpy (pp_info -> dst_addr , ptr , dst_address_length );
13491390 if (inet_pton (sa_family , pp_info -> dst_addr , & dst_sin_addr ) != 1 )
13501391 {
@@ -1365,7 +1406,7 @@ static int32_t pp1_parse_hdr(const uint8_t *buffer, uint32_t buffer_length, pp_i
13651406 {
13661407 return - ERR_PP1_SRC_PORT ;
13671408 }
1368- src_port_length = src_port_end - ptr ;
1409+ src_port_length = ( uint16_t )( src_port_end - ptr ) ;
13691410 if (src_port_length == 0 || src_port_length > 5 )
13701411 {
13711412 return - ERR_PP1_SRC_PORT ;
@@ -1390,7 +1431,7 @@ static int32_t pp1_parse_hdr(const uint8_t *buffer, uint32_t buffer_length, pp_i
13901431 {
13911432 return - ERR_PP1_DST_PORT ;
13921433 }
1393- dst_port_length = dst_port_end - ptr ;
1434+ dst_port_length = ( uint16_t )( dst_port_end - ptr ) ;
13941435 if (dst_port_length == 0 || dst_port_length > 5 )
13951436 {
13961437 return - ERR_PP1_DST_PORT ;
0 commit comments