Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

bgpd: Ensure stream received has enough data #12454

Merged
merged 1 commit into from
Mar 31, 2023
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
79 changes: 25 additions & 54 deletions bgpd/bgp_attr.c
Original file line number Diff line number Diff line change
Expand Up @@ -2927,9 +2927,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);
Expand All @@ -2951,12 +2963,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);
Expand All @@ -2970,10 +2978,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
Expand All @@ -2998,19 +3003,6 @@ bgp_attr_psid_sub(uint8_t type, uint16_t length,
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
* SRGBs corresponds to a multiple of the SRGB size; to get
Expand All @@ -3034,12 +3026,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);
Expand Down Expand Up @@ -3073,39 +3061,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",
Expand Down