Merge pull request #13781 from FRRouting/mergify/bp/stable/8.5/pr-12454

bgpd: Ensure stream received has enough data (backport #12454)
This commit is contained in:
Donald Sharp 2023-06-13 15:07:46 -04:00 committed by GitHub
commit d134cb14c7
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

View File

@ -2979,9 +2979,21 @@ bgp_attr_psid_sub(uint8_t type, uint16_t length,
int srgb_count; int srgb_count;
uint8_t sid_type, sid_flags; 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 (type == BGP_PREFIX_SID_LABEL_INDEX) {
if (STREAM_READABLE(peer->curr) < length if (length != BGP_PREFIX_SID_LABEL_INDEX_LENGTH) {
|| length != BGP_PREFIX_SID_LABEL_INDEX_LENGTH) {
flog_err(EC_BGP_ATTR_LEN, flog_err(EC_BGP_ATTR_LEN,
"Prefix SID label index length is %hu instead of %u", "Prefix SID label index length is %hu instead of %u",
length, BGP_PREFIX_SID_LABEL_INDEX_LENGTH); 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 /* Store label index; subsequently, we'll check on
* address-family */ * address-family */
attr->label_index = label_index; attr->label_index = label_index;
} } else if (type == BGP_PREFIX_SID_IPV6) {
if (length != BGP_PREFIX_SID_IPV6_LENGTH) {
/* 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) {
flog_err(EC_BGP_ATTR_LEN, flog_err(EC_BGP_ATTR_LEN,
"Prefix SID IPv6 length is %hu instead of %u", "Prefix SID IPv6 length is %hu instead of %u",
length, BGP_PREFIX_SID_IPV6_LENGTH); 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_getw(peer->curr);
stream_get(&ipv6_sid, peer->curr, 16); stream_get(&ipv6_sid, peer->curr, 16);
} } else if (type == BGP_PREFIX_SID_ORIGINATOR_SRGB) {
/* Placeholder code for the Originator SRGB type */
else if (type == BGP_PREFIX_SID_ORIGINATOR_SRGB) {
/* /*
* ietf-idr-bgp-prefix-sid-05: * ietf-idr-bgp-prefix-sid-05:
* Length is the total length of the value portion of the * Length is the total length of the value portion of the
@ -3050,19 +3055,6 @@ bgp_attr_psid_sub(uint8_t type, uint16_t length,
args->total); args->total);
} }
/*
* 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 * Check that the portion of the TLV containing the sequence of
* SRGBs corresponds to a multiple of the SRGB size; to get * SRGBs corresponds to a multiple of the SRGB size; to get
@ -3086,12 +3078,8 @@ bgp_attr_psid_sub(uint8_t type, uint16_t length,
stream_get(&srgb_base, peer->curr, 3); stream_get(&srgb_base, peer->curr, 3);
stream_get(&srgb_range, peer->curr, 3); stream_get(&srgb_range, peer->curr, 3);
} }
} } else if (type == BGP_PREFIX_SID_VPN_SID) {
if (length != BGP_PREFIX_SID_VPN_SID_LENGTH) {
/* 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) {
flog_err(EC_BGP_ATTR_LEN, flog_err(EC_BGP_ATTR_LEN,
"Prefix SID VPN SID length is %hu instead of %u", "Prefix SID VPN SID length is %hu instead of %u",
length, BGP_PREFIX_SID_VPN_SID_LENGTH); 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; attr->srv6_vpn->sid_flags = sid_flags;
sid_copy(&attr->srv6_vpn->sid, &ipv6_sid); sid_copy(&attr->srv6_vpn->sid, &ipv6_sid);
attr->srv6_vpn = srv6_vpn_intern(attr->srv6_vpn); attr->srv6_vpn = srv6_vpn_intern(attr->srv6_vpn);
} } else if (type == BGP_PREFIX_SID_SRV6_L3_SERVICE) {
if (STREAM_READABLE(peer->curr) < 1) {
/* Placeholder code for the SRv6 L3 Service type */
else if (type == BGP_PREFIX_SID_SRV6_L3_SERVICE) {
if (STREAM_READABLE(peer->curr) < length) {
flog_err( flog_err(
EC_BGP_ATTR_LEN, EC_BGP_ATTR_LEN,
"Prefix SID SRv6 L3-Service length is %hu, but only %zu bytes remain", "Prefix SID SRV6 L3 Service not enough data left, it must be at least 1 byte");
length, STREAM_READABLE(peer->curr)); return bgp_attr_malformed(
return bgp_attr_malformed(args, args, BGP_NOTIFY_UPDATE_ATTR_LENG_ERR,
BGP_NOTIFY_UPDATE_ATTR_LENG_ERR,
args->total); args->total);
} }
/* ignore reserved */ /* ignore reserved */
stream_getc(peer->curr); stream_getc(peer->curr);
return bgp_attr_srv6_service(args); return bgp_attr_srv6_service(args);
} }
/* Placeholder code for Unsupported TLV */ /* Placeholder code for Unsupported TLV */
else { 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)) if (bgp_debug_update(peer, NULL, NULL, 1))
zlog_debug( zlog_debug(
"%s attr Prefix-SID sub-type=%u is not supported, skipped", "%s attr Prefix-SID sub-type=%u is not supported, skipped",