Skip to content

Commit d134cb1

Browse files
authored
Merge pull request #13781 from FRRouting/mergify/bp/stable/8.5/pr-12454
bgpd: Ensure stream received has enough data (backport #12454)
2 parents 60aaf26 + 4d217e5 commit d134cb1

File tree

1 file changed

+25
-54
lines changed

1 file changed

+25
-54
lines changed

bgpd/bgp_attr.c

Lines changed: 25 additions & 54 deletions
Original file line numberDiff line numberDiff line change
@@ -2979,9 +2979,21 @@ bgp_attr_psid_sub(uint8_t type, uint16_t length,
29792979
int srgb_count;
29802980
uint8_t sid_type, sid_flags;
29812981

2982+
/*
2983+
* Check that we actually have at least as much data as
2984+
* specified by the length field
2985+
*/
2986+
if (STREAM_READABLE(peer->curr) < length) {
2987+
flog_err(
2988+
EC_BGP_ATTR_LEN,
2989+
"Prefix SID specifies length %hu, but only %zu bytes remain",
2990+
length, STREAM_READABLE(peer->curr));
2991+
return bgp_attr_malformed(args, BGP_NOTIFY_UPDATE_ATTR_LENG_ERR,
2992+
args->total);
2993+
}
2994+
29822995
if (type == BGP_PREFIX_SID_LABEL_INDEX) {
2983-
if (STREAM_READABLE(peer->curr) < length
2984-
|| length != BGP_PREFIX_SID_LABEL_INDEX_LENGTH) {
2996+
if (length != BGP_PREFIX_SID_LABEL_INDEX_LENGTH) {
29852997
flog_err(EC_BGP_ATTR_LEN,
29862998
"Prefix SID label index length is %hu instead of %u",
29872999
length, BGP_PREFIX_SID_LABEL_INDEX_LENGTH);
@@ -3003,12 +3015,8 @@ bgp_attr_psid_sub(uint8_t type, uint16_t length,
30033015
/* Store label index; subsequently, we'll check on
30043016
* address-family */
30053017
attr->label_index = label_index;
3006-
}
3007-
3008-
/* Placeholder code for the IPv6 SID type */
3009-
else if (type == BGP_PREFIX_SID_IPV6) {
3010-
if (STREAM_READABLE(peer->curr) < length
3011-
|| length != BGP_PREFIX_SID_IPV6_LENGTH) {
3018+
} else if (type == BGP_PREFIX_SID_IPV6) {
3019+
if (length != BGP_PREFIX_SID_IPV6_LENGTH) {
30123020
flog_err(EC_BGP_ATTR_LEN,
30133021
"Prefix SID IPv6 length is %hu instead of %u",
30143022
length, BGP_PREFIX_SID_IPV6_LENGTH);
@@ -3022,10 +3030,7 @@ bgp_attr_psid_sub(uint8_t type, uint16_t length,
30223030
stream_getw(peer->curr);
30233031

30243032
stream_get(&ipv6_sid, peer->curr, 16);
3025-
}
3026-
3027-
/* Placeholder code for the Originator SRGB type */
3028-
else if (type == BGP_PREFIX_SID_ORIGINATOR_SRGB) {
3033+
} else if (type == BGP_PREFIX_SID_ORIGINATOR_SRGB) {
30293034
/*
30303035
* ietf-idr-bgp-prefix-sid-05:
30313036
* 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,
30503055
args->total);
30513056
}
30523057

3053-
/*
3054-
* Check that we actually have at least as much data as
3055-
* specified by the length field
3056-
*/
3057-
if (STREAM_READABLE(peer->curr) < length) {
3058-
flog_err(EC_BGP_ATTR_LEN,
3059-
"Prefix SID Originator SRGB specifies length %hu, but only %zu bytes remain",
3060-
length, STREAM_READABLE(peer->curr));
3061-
return bgp_attr_malformed(
3062-
args, BGP_NOTIFY_UPDATE_ATTR_LENG_ERR,
3063-
args->total);
3064-
}
3065-
30663058
/*
30673059
* Check that the portion of the TLV containing the sequence of
30683060
* 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,
30863078
stream_get(&srgb_base, peer->curr, 3);
30873079
stream_get(&srgb_range, peer->curr, 3);
30883080
}
3089-
}
3090-
3091-
/* Placeholder code for the VPN-SID Service type */
3092-
else if (type == BGP_PREFIX_SID_VPN_SID) {
3093-
if (STREAM_READABLE(peer->curr) < length
3094-
|| length != BGP_PREFIX_SID_VPN_SID_LENGTH) {
3081+
} else if (type == BGP_PREFIX_SID_VPN_SID) {
3082+
if (length != BGP_PREFIX_SID_VPN_SID_LENGTH) {
30953083
flog_err(EC_BGP_ATTR_LEN,
30963084
"Prefix SID VPN SID length is %hu instead of %u",
30973085
length, BGP_PREFIX_SID_VPN_SID_LENGTH);
@@ -3125,39 +3113,22 @@ bgp_attr_psid_sub(uint8_t type, uint16_t length,
31253113
attr->srv6_vpn->sid_flags = sid_flags;
31263114
sid_copy(&attr->srv6_vpn->sid, &ipv6_sid);
31273115
attr->srv6_vpn = srv6_vpn_intern(attr->srv6_vpn);
3128-
}
3129-
3130-
/* Placeholder code for the SRv6 L3 Service type */
3131-
else if (type == BGP_PREFIX_SID_SRV6_L3_SERVICE) {
3132-
if (STREAM_READABLE(peer->curr) < length) {
3116+
} else if (type == BGP_PREFIX_SID_SRV6_L3_SERVICE) {
3117+
if (STREAM_READABLE(peer->curr) < 1) {
31333118
flog_err(
31343119
EC_BGP_ATTR_LEN,
3135-
"Prefix SID SRv6 L3-Service length is %hu, but only %zu bytes remain",
3136-
length, STREAM_READABLE(peer->curr));
3137-
return bgp_attr_malformed(args,
3138-
BGP_NOTIFY_UPDATE_ATTR_LENG_ERR,
3139-
args->total);
3120+
"Prefix SID SRV6 L3 Service not enough data left, it must be at least 1 byte");
3121+
return bgp_attr_malformed(
3122+
args, BGP_NOTIFY_UPDATE_ATTR_LENG_ERR,
3123+
args->total);
31403124
}
3141-
31423125
/* ignore reserved */
31433126
stream_getc(peer->curr);
31443127

31453128
return bgp_attr_srv6_service(args);
31463129
}
3147-
31483130
/* Placeholder code for Unsupported TLV */
31493131
else {
3150-
3151-
if (STREAM_READABLE(peer->curr) < length) {
3152-
flog_err(
3153-
EC_BGP_ATTR_LEN,
3154-
"Prefix SID SRv6 length is %hu - too long, only %zu remaining in this UPDATE",
3155-
length, STREAM_READABLE(peer->curr));
3156-
return bgp_attr_malformed(
3157-
args, BGP_NOTIFY_UPDATE_ATTR_LENG_ERR,
3158-
args->total);
3159-
}
3160-
31613132
if (bgp_debug_update(peer, NULL, NULL, 1))
31623133
zlog_debug(
31633134
"%s attr Prefix-SID sub-type=%u is not supported, skipped",

0 commit comments

Comments
 (0)