diff options
| author | Donald Sharp <donaldsharp72@gmail.com> | 2023-06-13 15:07:46 -0400 | 
|---|---|---|
| committer | GitHub <noreply@github.com> | 2023-06-13 15:07:46 -0400 | 
| commit | d134cb14c7c74e946e2a74f635a1ea28a444bf6c (patch) | |
| tree | 8e8cd3a18970b86f1e8cbb6510eb6641fbcd6a33 | |
| parent | 60aaf2627fa5a1e844490289b8004bbb1fb7f998 (diff) | |
| parent | 4d217e5d288893ca7f0ca415ad196761c120f8d9 (diff) | |
Merge pull request #13781 from FRRouting/mergify/bp/stable/8.5/pr-12454
bgpd: Ensure stream received has enough data (backport #12454)
| -rw-r--r-- | bgpd/bgp_attr.c | 79 | 
1 files changed, 25 insertions, 54 deletions
diff --git a/bgpd/bgp_attr.c b/bgpd/bgp_attr.c index b3421d3a24..18299bbce5 100644 --- a/bgpd/bgp_attr.c +++ b/bgpd/bgp_attr.c @@ -2979,9 +2979,21 @@ bgp_attr_psid_sub(uint8_t type, uint16_t length,  	int srgb_count;  	uint8_t sid_type, sid_flags; +	/* +	 * Check that we actually have at least as much data as +	 * specified by the length field +	 */ +	if (STREAM_READABLE(peer->curr) < length) { +		flog_err( +			EC_BGP_ATTR_LEN, +			"Prefix SID specifies length %hu, but only %zu bytes remain", +			length, STREAM_READABLE(peer->curr)); +		return bgp_attr_malformed(args, BGP_NOTIFY_UPDATE_ATTR_LENG_ERR, +					  args->total); +	} +  	if (type == BGP_PREFIX_SID_LABEL_INDEX) { -		if (STREAM_READABLE(peer->curr) < length -		    || length != BGP_PREFIX_SID_LABEL_INDEX_LENGTH) { +		if (length != BGP_PREFIX_SID_LABEL_INDEX_LENGTH) {  			flog_err(EC_BGP_ATTR_LEN,  				 "Prefix SID label index length is %hu instead of %u",  				 length, BGP_PREFIX_SID_LABEL_INDEX_LENGTH); @@ -3003,12 +3015,8 @@ bgp_attr_psid_sub(uint8_t type, uint16_t length,  		/* Store label index; subsequently, we'll check on  		 * address-family */  		attr->label_index = label_index; -	} - -	/* Placeholder code for the IPv6 SID type */ -	else if (type == BGP_PREFIX_SID_IPV6) { -		if (STREAM_READABLE(peer->curr) < length -		    || length != BGP_PREFIX_SID_IPV6_LENGTH) { +	} else if (type == BGP_PREFIX_SID_IPV6) { +		if (length != BGP_PREFIX_SID_IPV6_LENGTH) {  			flog_err(EC_BGP_ATTR_LEN,  				 "Prefix SID IPv6 length is %hu instead of %u",  				 length, BGP_PREFIX_SID_IPV6_LENGTH); @@ -3022,10 +3030,7 @@ bgp_attr_psid_sub(uint8_t type, uint16_t length,  		stream_getw(peer->curr);  		stream_get(&ipv6_sid, peer->curr, 16); -	} - -	/* Placeholder code for the Originator SRGB type */ -	else if (type == BGP_PREFIX_SID_ORIGINATOR_SRGB) { +	} else if (type == BGP_PREFIX_SID_ORIGINATOR_SRGB) {  		/*  		 * ietf-idr-bgp-prefix-sid-05:  		 *     Length is the total length of the value portion of the @@ -3051,19 +3056,6 @@ bgp_attr_psid_sub(uint8_t type, uint16_t length,  		}  		/* -		 * Check that we actually have at least as much data as -		 * specified by the length field -		 */ -		if (STREAM_READABLE(peer->curr) < length) { -			flog_err(EC_BGP_ATTR_LEN, -				 "Prefix SID Originator SRGB specifies length %hu, but only %zu bytes remain", -				 length, STREAM_READABLE(peer->curr)); -			return bgp_attr_malformed( -				args, BGP_NOTIFY_UPDATE_ATTR_LENG_ERR, -				args->total); -		} - -		/*  		 * Check that the portion of the TLV containing the sequence of  		 * SRGBs corresponds to a multiple of the SRGB size; to get  		 * that length, we skip the 16 bit flags field @@ -3086,12 +3078,8 @@ bgp_attr_psid_sub(uint8_t type, uint16_t length,  			stream_get(&srgb_base, peer->curr, 3);  			stream_get(&srgb_range, peer->curr, 3);  		} -	} - -	/* Placeholder code for the VPN-SID Service type */ -	else if (type == BGP_PREFIX_SID_VPN_SID) { -		if (STREAM_READABLE(peer->curr) < length -		    || length != BGP_PREFIX_SID_VPN_SID_LENGTH) { +	} else if (type == BGP_PREFIX_SID_VPN_SID) { +		if (length != BGP_PREFIX_SID_VPN_SID_LENGTH) {  			flog_err(EC_BGP_ATTR_LEN,  				 "Prefix SID VPN SID length is %hu instead of %u",  				 length, BGP_PREFIX_SID_VPN_SID_LENGTH); @@ -3125,39 +3113,22 @@ bgp_attr_psid_sub(uint8_t type, uint16_t length,  		attr->srv6_vpn->sid_flags = sid_flags;  		sid_copy(&attr->srv6_vpn->sid, &ipv6_sid);  		attr->srv6_vpn = srv6_vpn_intern(attr->srv6_vpn); -	} - -	/* Placeholder code for the SRv6 L3 Service type */ -	else if (type == BGP_PREFIX_SID_SRV6_L3_SERVICE) { -		if (STREAM_READABLE(peer->curr) < length) { +	} else if (type == BGP_PREFIX_SID_SRV6_L3_SERVICE) { +		if (STREAM_READABLE(peer->curr) < 1) {  			flog_err(  				EC_BGP_ATTR_LEN, -				"Prefix SID SRv6 L3-Service length is %hu, but only %zu bytes remain", -				length, STREAM_READABLE(peer->curr)); -			return bgp_attr_malformed(args, -				 BGP_NOTIFY_UPDATE_ATTR_LENG_ERR, -				 args->total); +				"Prefix SID SRV6 L3 Service not enough data left, it must be at least 1 byte"); +			return bgp_attr_malformed( +				args, BGP_NOTIFY_UPDATE_ATTR_LENG_ERR, +				args->total);  		} -  		/* ignore reserved */  		stream_getc(peer->curr);  		return bgp_attr_srv6_service(args);  	} -  	/* Placeholder code for Unsupported TLV */  	else { - -		if (STREAM_READABLE(peer->curr) < length) { -			flog_err( -				EC_BGP_ATTR_LEN, -				"Prefix SID SRv6 length is %hu - too long, only %zu remaining in this UPDATE", -				length, STREAM_READABLE(peer->curr)); -			return bgp_attr_malformed( -				args, BGP_NOTIFY_UPDATE_ATTR_LENG_ERR, -				args->total); -		} -  		if (bgp_debug_update(peer, NULL, NULL, 1))  			zlog_debug(  				"%s attr Prefix-SID sub-type=%u is not supported, skipped",  | 
