@@ -217,7 +217,7 @@ static uint8_t parse_port(const char *value, uint16_t *usport)
217217{
218218 char * endptr = NULL ;
219219 uint64_t port = strtoul (value , & endptr , 10 );
220- if (endptr == value || port > UINT16_MAX )
220+ if (endptr == value || * endptr != '\0' || * value == '+' || port > UINT16_MAX )
221221 {
222222 return 0 ;
223223 }
@@ -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 ;
@@ -674,7 +701,8 @@ static uint32_t crc32c(const uint8_t* buf, uint32_t len)
674701static uint8_t * pp2_create_hdr (const pp_info_t * pp_info , uint16_t * pp2_hdr_len , int32_t * error )
675702{
676703 proxy_hdr_v2_t proxy_hdr_v2 = { PP2_SIG , '\x21' , 0 , 0 };
677- uint16_t proxy_addr_len , len , padding_bytes , index ;
704+ uint16_t proxy_addr_len , padding_bytes , index ;
705+ uint32_t len ;
678706 proxy_addr_t proxy_addr ;
679707 const tlv_array_t * tlv_array ;
680708 uint32_t i ;
@@ -755,7 +783,12 @@ static uint8_t *pp2_create_hdr(const pp_info_t *pp_info, uint16_t *pp2_hdr_len,
755783 {
756784 len += sizeof_pp2_tlv_t + sizeof (uint32_t );
757785 }
758- * pp2_hdr_len = sizeof (proxy_hdr_v2_t ) + len ;
786+ if (sizeof (proxy_hdr_v2_t ) + len > UINT16_MAX )
787+ {
788+ * error = - ERR_PP2_LENGTH ;
789+ return NULL ;
790+ }
791+ * pp2_hdr_len = (uint16_t )(sizeof (proxy_hdr_v2_t ) + len );
759792 if (pp_info -> pp2_info .alignment_power > 1 )
760793 {
761794 uint16_t alignment = 1 << pp_info -> pp2_info .alignment_power ;
@@ -767,13 +800,13 @@ static uint8_t *pp2_create_hdr(const pp_info_t *pp_info, uint16_t *pp2_hdr_len,
767800 {
768801 pp2_hdr_len_padded += alignment ;
769802 }
770- padding_bytes = pp2_hdr_len_padded - sizeof (proxy_hdr_v2_t ) - len - sizeof_pp2_tlv_t ;
803+ padding_bytes = pp2_hdr_len_padded - ( uint16_t ) sizeof (proxy_hdr_v2_t ) - ( uint16_t ) len - sizeof_pp2_tlv_t ;
771804
772805 * pp2_hdr_len = pp2_hdr_len_padded ;
773- len = pp2_hdr_len_padded - sizeof (proxy_hdr_v2_t );
806+ len = pp2_hdr_len_padded - ( uint32_t ) sizeof (proxy_hdr_v2_t );
774807 }
775808 }
776- proxy_hdr_v2 .len = htons (len );
809+ proxy_hdr_v2 .len = htons (( uint16_t ) len );
777810
778811 /* Create the PROXY protocol header */
779812 pp2_hdr = malloc (* pp2_hdr_len );
@@ -795,7 +828,7 @@ static uint8_t *pp2_create_hdr(const pp_info_t *pp_info, uint16_t *pp2_hdr_len,
795828 memcpy (pp2_hdr + index , tlv_array -> tlvs [i ], tlv_len );
796829 index += tlv_len ;
797830 }
798- if (pp_info -> pp2_info .alignment_power > 1 )
831+ if (pp_info -> pp2_info .alignment_power > 1 && padding_bytes > 0 )
799832 {
800833 pp2_tlv_t tlv = { 0 };
801834 tlv .type = PP2_TYPE_NOOP ;
@@ -884,7 +917,7 @@ static uint8_t *pp1_create_hdr(const pp_info_t *pp_info, uint16_t *pp1_hdr_len,
884917 }
885918 memcpy (src_addr , pp_info -> src_addr , sizeof (src_addr ));
886919 memcpy (dst_addr , pp_info -> dst_addr , sizeof (dst_addr ));
887- * pp1_hdr_len = _sprintf (block , "PROXY %s %s %s %hu %hu" CRLF , fam , src_addr , dst_addr , pp_info -> src_port , pp_info -> dst_port );
920+ * pp1_hdr_len = ( uint16_t ) _sprintf (block , "PROXY %s %s %s %hu %hu" CRLF , fam , src_addr , dst_addr , pp_info -> src_port , pp_info -> dst_port );
888921 }
889922 else
890923 {
@@ -1055,12 +1088,12 @@ static int32_t pp2_parse_hdr(const uint8_t *buffer, uint32_t buffer_length, pp_i
10551088 }
10561089
10571090 /* TLVs */
1058- /* Any TLV vector must be at least 3 bytes */
1059- while (tlv_vectors_len > sizeof_pp2_tlv_t )
1091+ /* Any TLV vector must be at least 3 bytes (sizeof_pp2_tlv_t) */
1092+ while (tlv_vectors_len >= sizeof_pp2_tlv_t )
10601093 {
10611094 const pp2_tlv_t * pp2_tlv = (const pp2_tlv_t * ) buffer ;
10621095 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 ;
1096+ uint32_t pp2_tlv_offset = ( uint32_t ) sizeof_pp2_tlv_t + pp2_tlv_len ;
10641097 if (pp2_tlv_offset > tlv_vectors_len )
10651098 {
10661099 return - ERR_PP2_TLV_LENGTH ;
@@ -1094,7 +1127,7 @@ static int32_t pp2_parse_hdr(const uint8_t *buffer, uint32_t buffer_length, pp_i
10941127 * Instead of zeroing the field in the buffer, compute CRC in 3 segments:
10951128 * before the checksum value, 4 zero bytes, after the checksum value. */
10961129 total_hdr_len = sizeof (proxy_hdr_v2_t ) + len ;
1097- offset_to_chksum_value = (const uint8_t * )pp2_tlv -> value - pp2_hdr ;
1130+ offset_to_chksum_value = (uint32_t )(( const uint8_t * )pp2_tlv -> value - pp2_hdr ) ;
10981131 after_chksum_offset = offset_to_chksum_value + sizeof (uint32_t );
10991132
11001133 crc = crc32c_continue (0xffffffff , pp2_hdr , offset_to_chksum_value );
@@ -1129,25 +1162,39 @@ static int32_t pp2_parse_hdr(const uint8_t *buffer, uint32_t buffer_length, pp_i
11291162 break ;
11301163 case PP2_TYPE_SSL :
11311164 {
1132- const pp2_tlv_ssl_t * pp2_tlv_ssl = ( const pp2_tlv_ssl_t * ) pp2_tlv -> value ;
1165+ const pp2_tlv_ssl_t * pp2_tlv_ssl ;
11331166 uint16_t pp2_tlvs_ssl_len = 0 , pp2_sub_tlv_offset = 0 ;
11341167 uint8_t tlv_ssl_version_found = 0 ;
11351168
1169+ if (pp2_tlv_len < sizeof (((pp2_tlv_ssl_t * )0 )-> client ) + sizeof (((pp2_tlv_ssl_t * )0 )-> verify ))
1170+ {
1171+ return - ERR_PP2_TYPE_SSL ;
1172+ }
1173+
1174+ pp2_tlv_ssl = (const pp2_tlv_ssl_t * ) pp2_tlv -> value ;
1175+
11361176 /* Set the pp2_ssl_info */
11371177 pp_info -> pp2_info .pp2_ssl_info .ssl = !!(pp2_tlv_ssl -> client & PP2_CLIENT_SSL );
11381178 pp_info -> pp2_info .pp2_ssl_info .cert_in_connection = !!(pp2_tlv_ssl -> client & PP2_CLIENT_CERT_CONN );
11391179 pp_info -> pp2_info .pp2_ssl_info .cert_in_session = !!(pp2_tlv_ssl -> client & PP2_CLIENT_CERT_SESS );
11401180 pp_info -> pp2_info .pp2_ssl_info .cert_verified = !pp2_tlv_ssl -> verify ;
11411181
11421182 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 )
1183+ while (pp2_sub_tlv_offset + sizeof_pp2_tlv_t <= pp2_tlvs_ssl_len )
11441184 {
11451185 const pp2_tlv_t * pp2_sub_tlv_ssl = (const pp2_tlv_t * ) ((const uint8_t * ) pp2_tlv_ssl -> sub_tlv + pp2_sub_tlv_offset );
11461186 uint16_t pp2_sub_tlv_ssl_len = pp2_sub_tlv_ssl -> length_hi << 8 | pp2_sub_tlv_ssl -> length_lo ;
1187+ if ((uint32_t ) sizeof_pp2_tlv_t + pp2_sub_tlv_ssl_len > (uint32_t )(pp2_tlvs_ssl_len - pp2_sub_tlv_offset ))
1188+ {
1189+ return - ERR_PP2_TYPE_SSL ;
1190+ }
1191+ if (pp2_sub_tlv_ssl -> type == PP2_SUBTYPE_SSL_VERSION )
1192+ {
1193+ tlv_ssl_version_found = 1 ;
1194+ }
11471195 switch (pp2_sub_tlv_ssl -> type )
11481196 {
11491197 case PP2_SUBTYPE_SSL_VERSION : /* US-ASCII */
1150- tlv_ssl_version_found = 1 ;
11511198 case PP2_SUBTYPE_SSL_CIPHER : /* US-ASCII */
11521199 case PP2_SUBTYPE_SSL_SIG_ALG : /* US-ASCII */
11531200 case PP2_SUBTYPE_SSL_KEY_ALG : /* US-ASCII */
@@ -1171,7 +1218,7 @@ static int32_t pp2_parse_hdr(const uint8_t *buffer, uint32_t buffer_length, pp_i
11711218
11721219 pp2_sub_tlv_offset += sizeof_pp2_tlv_t + pp2_sub_tlv_ssl_len ;
11731220 }
1174- if (pp2_sub_tlv_offset > pp2_tlvs_ssl_len || (pp_info -> pp2_info .pp2_ssl_info .ssl && !tlv_ssl_version_found ))
1221+ if (pp2_sub_tlv_offset != pp2_tlvs_ssl_len || (pp_info -> pp2_info .pp2_ssl_info .ssl && !tlv_ssl_version_found ))
11751222 {
11761223 return - ERR_PP2_TYPE_SSL ;
11771224 }
@@ -1213,8 +1260,7 @@ static int32_t pp2_parse_hdr(const uint8_t *buffer, uint32_t buffer_length, pp_i
12131260 /* Connection is done through Private Link service */
12141261 if (pp2_tlv_azure -> type == PP2_SUBTYPE_AZURE_PRIVATEENDPOINT_LINKID ) /* 32-bit number */
12151262 {
1216- pp2_tlv_t * tlv = tlv_new (pp2_tlv -> type , pp2_tlv_len , pp2_tlv -> value );
1217- if (!tlv || !tlv_array_append_tlv (& pp_info -> pp2_info .tlv_array , tlv ))
1263+ if (!tlv_array_append_tlv_new (& pp_info -> pp2_info .tlv_array , pp2_tlv -> type , pp2_tlv_len , pp2_tlv -> value ))
12181264 {
12191265 return - ERR_HEAP_ALLOC ;
12201266 }
@@ -1248,15 +1294,15 @@ static int32_t pp1_parse_hdr(const uint8_t *buffer, uint32_t buffer_length, pp_i
12481294 char src_port_str [6 ] = { 0 };
12491295 char dst_port_str [6 ] = { 0 };
12501296
1251- memcpy (block , buffer , buffer_length < PP1_MAX_LENGTH ? buffer_length : PP1_MAX_LENGTH );
1297+ memcpy (block , buffer , buffer_length < PP1_MAX_LENGTH - 1 ? buffer_length : PP1_MAX_LENGTH - 1 );
12521298
12531299 block_end = strstr (block , CRLF );
12541300 if (!block_end )
12551301 {
12561302 return - ERR_PP1_CRLF ;
12571303 }
12581304 block_end += strlen (CRLF );
1259- pp1_hdr_len = block_end - block ;
1305+ pp1_hdr_len = ( int32_t )( block_end - block ) ;
12601306
12611307 /* PROXY */
12621308 if (memcmp (block , "PROXY" , 5 ))
@@ -1277,7 +1323,7 @@ static int32_t pp1_parse_hdr(const uint8_t *buffer, uint32_t buffer_length, pp_i
12771323 if (!inet_family )
12781324 {
12791325 /* Unknown connection (short form) */
1280- if (pp1_hdr_len == 15 || !memcmp (ptr , "UNKNOWN" , 7 ))
1326+ if (pp1_hdr_len == 15 && !memcmp (ptr , "UNKNOWN" , 7 ))
12811327 {
12821328 pp_info -> address_family = ADDR_FAMILY_UNSPEC ;
12831329 pp_info -> transport_protocol = TRANSPORT_PROTOCOL_UNSPEC ;
@@ -1324,7 +1370,7 @@ static int32_t pp1_parse_hdr(const uint8_t *buffer, uint32_t buffer_length, pp_i
13241370 {
13251371 return sa_family == AF_INET ? - ERR_PP1_IPV4_SRC_IP : - ERR_PP1_IPV6_SRC_IP ;
13261372 }
1327- src_address_length = src_address_end - ptr ;
1373+ src_address_length = ( uint16_t )( src_address_end - ptr ) ;
13281374 memcpy (pp_info -> src_addr , ptr , src_address_length );
13291375 if (inet_pton (sa_family , pp_info -> src_addr , & src_sin_addr ) != 1 )
13301376 {
@@ -1345,7 +1391,7 @@ static int32_t pp1_parse_hdr(const uint8_t *buffer, uint32_t buffer_length, pp_i
13451391 {
13461392 return sa_family == AF_INET ? - ERR_PP1_IPV4_DST_IP : - ERR_PP1_IPV6_DST_IP ;
13471393 }
1348- dst_address_length = dst_address_end - ptr ;
1394+ dst_address_length = ( uint16_t )( dst_address_end - ptr ) ;
13491395 memcpy (pp_info -> dst_addr , ptr , dst_address_length );
13501396 if (inet_pton (sa_family , pp_info -> dst_addr , & dst_sin_addr ) != 1 )
13511397 {
@@ -1366,7 +1412,7 @@ static int32_t pp1_parse_hdr(const uint8_t *buffer, uint32_t buffer_length, pp_i
13661412 {
13671413 return - ERR_PP1_SRC_PORT ;
13681414 }
1369- src_port_length = src_port_end - ptr ;
1415+ src_port_length = ( uint16_t )( src_port_end - ptr ) ;
13701416 if (src_port_length == 0 || src_port_length > 5 )
13711417 {
13721418 return - ERR_PP1_SRC_PORT ;
@@ -1391,7 +1437,7 @@ static int32_t pp1_parse_hdr(const uint8_t *buffer, uint32_t buffer_length, pp_i
13911437 {
13921438 return - ERR_PP1_DST_PORT ;
13931439 }
1394- dst_port_length = dst_port_end - ptr ;
1440+ dst_port_length = ( uint16_t )( dst_port_end - ptr ) ;
13951441 if (dst_port_length == 0 || dst_port_length > 5 )
13961442 {
13971443 return - ERR_PP1_DST_PORT ;
0 commit comments