From 694815f1d322684373c6c4cacb1744e0f7b1278d578eedfd68288189e624fb1c Mon Sep 17 00:00:00 2001 From: Marcus Meissner Date: Thu, 1 Jun 2023 10:02:15 +0000 Subject: [PATCH] Accepting request 1088895 from home:mtomaschewski:branches:network - Apply upstream fix for denial of service via the bgp_capability_llgr() function (bsc#1211248,CVE-2023-31489,gh#FRRouting/frr#13098). [+ 0006-bgpd-Check-7-bytes-for-Long-lived-Graceful-Restart-c.patch] - Apply upstream fix for denial of service via the bgp_attr_psid_sub() function (bsc#1211249,CVE-2023-31490,gh#FRRouting/frr#13099). [+ 0007-bgpd-Ensure-stream-received-has-enough-data.patch] OBS-URL: https://build.opensuse.org/request/show/1088895 OBS-URL: https://build.opensuse.org/package/show/network/frr?expand=0&rev=49 --- ...es-for-Long-lived-Graceful-Restart-c.patch | 48 ++++++ ...sure-stream-received-has-enough-data.patch | 155 ++++++++++++++++++ frr.changes | 10 ++ frr.spec | 4 + 4 files changed, 217 insertions(+) create mode 100644 0006-bgpd-Check-7-bytes-for-Long-lived-Graceful-Restart-c.patch create mode 100644 0007-bgpd-Ensure-stream-received-has-enough-data.patch diff --git a/0006-bgpd-Check-7-bytes-for-Long-lived-Graceful-Restart-c.patch b/0006-bgpd-Check-7-bytes-for-Long-lived-Graceful-Restart-c.patch new file mode 100644 index 0000000..92e4394 --- /dev/null +++ b/0006-bgpd-Check-7-bytes-for-Long-lived-Graceful-Restart-c.patch @@ -0,0 +1,48 @@ +From d95229c9ba4c8ff99dfc644dd2d1e9e172fe3faf Mon Sep 17 00:00:00 2001 +From: Donatas Abraitis +Date: Fri, 24 Mar 2023 09:55:23 +0200 +Upstream: yes +References: bsc#1211248,CVE-2023-31489,https://github.com/FRRouting/frr/pull/13100/commits/b1d33ec293e8e36fbb8766252f3b016d268e31ce +Subject: [PATCH] bgpd: Check 7 bytes for Long-lived Graceful-Restart + capability + +It's not 4 bytes, it was assuming the same as Graceful-Restart tuples. + +LLGR has more 3 bytes (Long-lived Stale Time). + +Signed-off-by: Donatas Abraitis +Signed-off-by: Marius Tomaschewski + +diff --git a/bgpd/bgp_open.c b/bgpd/bgp_open.c +index d1667fac26..907e75e76b 100644 +--- a/bgpd/bgp_open.c ++++ b/bgpd/bgp_open.c +@@ -599,12 +599,24 @@ static int bgp_capability_restart(struct peer *peer, + static int bgp_capability_llgr(struct peer *peer, + struct capability_header *caphdr) + { ++/* ++ * +--------------------------------------------------+ ++ * | Address Family Identifier (16 bits) | ++ * +--------------------------------------------------+ ++ * | Subsequent Address Family Identifier (8 bits) | ++ * +--------------------------------------------------+ ++ * | Flags for Address Family (8 bits) | ++ * +--------------------------------------------------+ ++ * | Long-lived Stale Time (24 bits) | ++ * +--------------------------------------------------+ ++ */ ++#define BGP_CAP_LLGR_MIN_PACKET_LEN 7 + struct stream *s = BGP_INPUT(peer); + size_t end = stream_get_getp(s) + caphdr->length; + + SET_FLAG(peer->cap, PEER_CAP_LLGR_RCV); + +- while (stream_get_getp(s) + 4 <= end) { ++ while (stream_get_getp(s) + BGP_CAP_LLGR_MIN_PACKET_LEN <= end) { + afi_t afi; + safi_t safi; + iana_afi_t pkt_afi = stream_getw(s); +-- +2.35.3 + diff --git a/0007-bgpd-Ensure-stream-received-has-enough-data.patch b/0007-bgpd-Ensure-stream-received-has-enough-data.patch new file mode 100644 index 0000000..aba1134 --- /dev/null +++ b/0007-bgpd-Ensure-stream-received-has-enough-data.patch @@ -0,0 +1,155 @@ +From 6d307ec2f5f5f9827f340a08941e6f78d09d1876 Mon Sep 17 00:00:00 2001 +From: Donald Sharp +Date: Tue, 6 Dec 2022 10:23:11 -0500 +Upstream: yes +References: bsc#1211249,CVE-2023-31490,https://github.com/FRRouting/frr/pull/12454/commits/06431bfa7570f169637ebb5898f0b0cc3b010802 +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 +Signed-off-by: Donald Sharp +Signed-off-by: Marius Tomaschewski + +diff --git a/bgpd/bgp_attr.c b/bgpd/bgp_attr.c +index b7d0958bac..c6177a1b93 100644 +--- a/bgpd/bgp_attr.c ++++ b/bgpd/bgp_attr.c +@@ -2748,9 +2748,21 @@ 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); +@@ -2772,12 +2784,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); +@@ -2791,10 +2799,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 +@@ -2819,19 +2824,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 +@@ -2855,12 +2847,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); +@@ -2896,39 +2884,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", +-- +2.35.3 + diff --git a/frr.changes b/frr.changes index 329f732..8f74574 100644 --- a/frr.changes +++ b/frr.changes @@ -1,3 +1,13 @@ +------------------------------------------------------------------- +Mon May 15 08:01:39 UTC 2023 - Marius Tomaschewski + +- Apply upstream fix for denial of service via the bgp_capability_llgr() + function (bsc#1211248,CVE-2023-31489,gh#FRRouting/frr#13098). + [+ 0006-bgpd-Check-7-bytes-for-Long-lived-Graceful-Restart-c.patch] +- Apply upstream fix for denial of service via the bgp_attr_psid_sub() + function (bsc#1211249,CVE-2023-31490,gh#FRRouting/frr#13099). + [+ 0007-bgpd-Ensure-stream-received-has-enough-data.patch] + ------------------------------------------------------------------- Mon Apr 3 14:00:27 UTC 2023 - Marius Tomaschewski diff --git a/frr.spec b/frr.spec index c5bcd38..94e1741 100644 --- a/frr.spec +++ b/frr.spec @@ -44,6 +44,8 @@ Patch2: harden_frr.service.patch Patch3: 0003-tools-Run-as-FRR_USER-install-chown-commands-to-avoi.patch Patch4: 0004-tools-remove-backslash-from-declare-check-regex.patch Patch5: 0005-root-ok-in-account-frr.pam.patch +Patch6: 0006-bgpd-Check-7-bytes-for-Long-lived-Graceful-Restart-c.patch +Patch7: 0007-bgpd-Ensure-stream-received-has-enough-data.patch BuildRequires: autoconf BuildRequires: automake BuildRequires: bison >= 2.7 @@ -187,6 +189,8 @@ developing OSPF-API and frr applications. %patch3 -p1 %patch4 -p1 %patch5 -p1 +%patch6 -p1 +%patch7 -p1 %build # GCC LTO objects must be "fat" to avoid assembly errors