frr: fix for CVE-2023-31490

An issue found in Frrouting bgpd v.8.4.2 allows a remote attacker to
cause a denial of service via the bgp_attr_psid_sub() function.

References:
https://nvd.nist.gov/vuln/detail/CVE-2023-31490
https://github.com/FRRouting/frr/issues/13099

Signed-off-by: Narpat Mali <narpat.mali@windriver.com>
[Fixup so patch would apply]
Signed-off-by: Armin Kuster <akuster808@gmail.com>
This commit is contained in:
Narpat Mali
2023-07-13 05:52:49 +00:00
committed by Armin Kuster
parent b541346589
commit 8ab74bed48
2 changed files with 161 additions and 0 deletions
@@ -0,0 +1,160 @@
From 72c13aac2eb7c8f3a10ad806d80ab635c28f4c04 Mon Sep 17 00:00:00 2001
From: Donald Sharp <sharpd@nvidia.com>
Date: Wed, 21 Jun 2023 15:24:50 +0000
Subject: [PATCH] bgpd: Ensure stream received has enough data
BGP_PREFIX_SID_SRV6_L3_SERVICE attributes must not
fully trust the length value specified in the nlri.
Always ensure that the amount of data we need to read
can be fullfilled.
Reported-by: Iggy Frankovic <iggyfran@amazon.com>
Signed-off-by: Donald Sharp <sharpd@nvidia.com>
CVE: CVE-2023-31490
Upstream-Status: Backport [https://github.com/FRRouting/frr/pull/12454/commits/06431bfa7570f169637ebb5898f0b0cc3b010802]
Signed-off-by: Narpat Mali <narpat.mali@windriver.com>
---
bgpd/bgp_attr.c | 79 ++++++++++++++++---------------------------------
1 file changed, 25 insertions(+), 54 deletions(-)
diff --git a/bgpd/bgp_attr.c b/bgpd/bgp_attr.c
index 2154baf4e..5d06991e2 100644
--- a/bgpd/bgp_attr.c
+++ b/bgpd/bgp_attr.c
@@ -2722,9 +2722,21 @@ static bgp_attr_parse_ret_t bgp_attr_psid_sub(uint8_t type, uint16_t length,
uint8_t sid_type, sid_flags;
char buf[BUFSIZ];
+ /*
+ * 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);
@@ -2746,12 +2758,8 @@ static bgp_attr_parse_ret_t 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);
@@ -2765,10 +2773,7 @@ static bgp_attr_parse_ret_t 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
@@ -2793,19 +2798,6 @@ static bgp_attr_parse_ret_t 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
@@ -2829,12 +2821,8 @@ static bgp_attr_parse_ret_t 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);
@@ -2870,39 +2858,22 @@ static bgp_attr_parse_ret_t 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",
--
2.40.0
@@ -17,6 +17,7 @@ SRC_URI = "git://github.com/FRRouting/frr.git;protocol=https;branch=stable/8.2 \
file://CVE-2022-40318.patch \
file://CVE-2022-43681.patch \
file://CVE-2023-31489.patch \
file://CVE-2023-31490.patch \
file://frr.pam \
"