diff mbox series

frr: fix for CVE-2023-31490

Message ID 20230622102345.2296870-1-narpat.mali@windriver.com
State New
Headers show
Series frr: fix for CVE-2023-31490 | expand

Commit Message

nmali June 22, 2023, 10:23 a.m. UTC
From: Narpat Mali <narpat.mali@windriver.com>

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>
---
 .../frr/frr/CVE-2023-31490.patch              | 160 ++++++++++++++++++
 .../recipes-protocols/frr/frr_8.2.2.bb        |   1 +
 2 files changed, 161 insertions(+)
 create mode 100644 meta-networking/recipes-protocols/frr/frr/CVE-2023-31490.patch
diff mbox series

Patch

diff --git a/meta-networking/recipes-protocols/frr/frr/CVE-2023-31490.patch b/meta-networking/recipes-protocols/frr/frr/CVE-2023-31490.patch
new file mode 100644
index 0000000000..d7b341d769
--- /dev/null
+++ b/meta-networking/recipes-protocols/frr/frr/CVE-2023-31490.patch
@@ -0,0 +1,160 @@ 
+From 72c13aac2eb7c8f3a10ad806d80ab635c28f4c04 Mon Sep 17 00:00:00 2001
+From: Narpat Mali <narpat.mali@windriver.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
diff --git a/meta-networking/recipes-protocols/frr/frr_8.2.2.bb b/meta-networking/recipes-protocols/frr/frr_8.2.2.bb
index 80f4729e1f..073657b652 100644
--- a/meta-networking/recipes-protocols/frr/frr_8.2.2.bb
+++ b/meta-networking/recipes-protocols/frr/frr_8.2.2.bb
@@ -13,6 +13,7 @@  SRC_URI = "git://github.com/FRRouting/frr.git;protocol=https;branch=stable/8.2 \
            file://CVE-2022-37035.patch \
            file://CVE-2022-37032.patch \
            file://CVE-2022-42917.patch \
+           file://CVE-2023-31490.patch \
            file://frr.pam \
 	      "