- Fix CVE-2023-38802

- bfdd: remove profiles when removing bfd node
This commit is contained in:
eabdullin 2023-09-20 14:58:47 +03:00
parent 5788752ec0
commit 45da74035f
3 changed files with 255 additions and 1 deletions

View File

@ -0,0 +1,117 @@
From 4b793d1eb35ab5794db12725a28fcdb4fef23af7 Mon Sep 17 00:00:00 2001
From: Igor Ryzhov <iryzhov@nfware.com>
Date: Thu, 1 Apr 2021 15:29:18 +0300
Subject: [PATCH] bfdd: remove profiles when removing bfd node
Fixes #8379.
Signed-off-by: Igor Ryzhov <iryzhov@nfware.com>
---
bfdd/bfd.c | 8 ++++++++
bfdd/bfd.h | 1 +
bfdd/bfdd_nb_config.c | 1 +
3 files changed, 10 insertions(+)
diff --git a/bfdd/bfd.c b/bfdd/bfd.c
index c966efd8ea71..cf292a836354 100644
--- a/bfdd/bfd.c
+++ b/bfdd/bfd.c
@@ -1889,6 +1889,14 @@ void bfd_sessions_remove_manual(void)
hash_iterate(bfd_key_hash, _bfd_session_remove_manual, NULL);
}
+void bfd_profiles_remove(void)
+{
+ struct bfd_profile *bp;
+
+ while ((bp = TAILQ_FIRST(&bplist)) != NULL)
+ bfd_profile_free(bp);
+}
+
/*
* Profile related hash functions.
*/
diff --git a/bfdd/bfd.h b/bfdd/bfd.h
index af3f92d6a8f8..9ee1da728717 100644
--- a/bfdd/bfd.h
+++ b/bfdd/bfd.h
@@ -596,6 +596,7 @@ void bfd_session_free(struct bfd_session *bs);
const struct bfd_session *bfd_session_next(const struct bfd_session *bs,
bool mhop);
void bfd_sessions_remove_manual(void);
+void bfd_profiles_remove(void);
/**
* Set the BFD session echo state.
diff --git a/bfdd/bfdd_nb_config.c b/bfdd/bfdd_nb_config.c
index 0046bc625b45..77f8cbd09c07 100644
--- a/bfdd/bfdd_nb_config.c
+++ b/bfdd/bfdd_nb_config.c
@@ -203,6 +203,7 @@ int bfdd_bfd_destroy(struct nb_cb_destroy_args *args)
case NB_EV_APPLY:
bfd_sessions_remove_manual();
+ bfd_profiles_remove();
break;
case NB_EV_ABORT:
diff --git a/bfdd/bfdd_nb_config.c b/bfdd/bfdd_nb_config.c
index 77f8cbd09c07..4030e2eefa50 100644
--- a/bfdd/bfdd_nb_config.c
+++ b/bfdd/bfdd_nb_config.c
@@ -186,7 +186,15 @@ static int bfd_session_destroy(enum nb_event event,
*/
int bfdd_bfd_create(struct nb_cb_create_args *args)
{
- /* NOTHING */
+ if (args->event != NB_EV_APPLY)
+ return NB_OK;
+
+ /*
+ * Set any non-NULL value to be able to call
+ * nb_running_unset_entry in bfdd_bfd_destroy.
+ */
+ nb_running_set_entry(args->dnode, (void *)0x1);
+
return NB_OK;
}
@@ -202,6 +210,12 @@ int bfdd_bfd_destroy(struct nb_cb_destroy_args *args)
return NB_OK;
case NB_EV_APPLY:
+ /*
+ * We need to call this to unset pointers from
+ * the child nodes - sessions and profiles.
+ */
+ nb_running_unset_entry(args->dnode);
+
bfd_sessions_remove_manual();
bfd_profiles_remove();
break;
diff --git a/bfdd/bfdd_cli.c b/bfdd/bfdd_cli.c
index b64e36b36a44..5a844e56e121 100644
--- a/bfdd/bfdd_cli.c
+++ b/bfdd/bfdd_cli.c
@@ -486,7 +486,7 @@ void bfd_cli_show_echo_interval(struct vty *vty, struct lyd_node *dnode,
* Profile commands.
*/
DEFPY_YANG_NOSH(bfd_profile, bfd_profile_cmd,
- "profile WORD$name",
+ "profile BFDPROF$name",
BFD_PROFILE_STR
BFD_PROFILE_NAME_STR)
{
diff --git a/vtysh/vtysh.c b/vtysh/vtysh.c
index 74f13e1a44e8..cf1811bb1f2f 100644
--- a/vtysh/vtysh.c
+++ b/vtysh/vtysh.c
@@ -1959,7 +1959,7 @@ DEFUNSH(VTYSH_BFDD, bfd_peer_enter, bfd_peer_enter_cmd,
}
DEFUNSH(VTYSH_BFDD, bfd_profile_enter, bfd_profile_enter_cmd,
- "profile WORD",
+ "profile BFDPROF",
BFD_PROFILE_STR
BFD_PROFILE_NAME_STR)
{

View File

@ -0,0 +1,128 @@
From bcb6b58d9530173df41d3a3cbc4c600ee0b4b186 Mon Sep 17 00:00:00 2001
From: Donatas Abraitis <donatas@opensourcerouting.org>
Date: Thu, 13 Jul 2023 22:32:03 +0300
Subject: [PATCH] bgpd: Use treat-as-withdraw for tunnel encapsulation
attribute
Before this path we used session reset method, which is discouraged by rfc7606.
Handle this as rfc requires.
Signed-off-by: Donatas Abraitis <donatas@opensourcerouting.org>
---
bgpd/bgp_attr.c | 61 ++++++++++++++++++++-----------------------------
1 file changed, 25 insertions(+), 36 deletions(-)
diff --git a/bgpd/bgp_attr.c b/bgpd/bgp_attr.c
index dcf0f4d47cfb..8c53191d680f 100644
--- a/bgpd/bgp_attr.c
+++ b/bgpd/bgp_attr.c
@@ -1301,6 +1301,7 @@ bgp_attr_malformed(struct bgp_attr_parser_args *args, uint8_t subcode,
case BGP_ATTR_LARGE_COMMUNITIES:
case BGP_ATTR_ORIGINATOR_ID:
case BGP_ATTR_CLUSTER_LIST:
+ case BGP_ATTR_ENCAP:
return BGP_ATTR_PARSE_WITHDRAW;
case BGP_ATTR_MP_REACH_NLRI:
case BGP_ATTR_MP_UNREACH_NLRI:
@@ -2434,26 +2435,21 @@ bgp_attr_ipv6_ext_communities(struct bgp_attr_parser_args *args)
}
/* Parse Tunnel Encap attribute in an UPDATE */
-static int bgp_attr_encap(uint8_t type, struct peer *peer, /* IN */
- bgp_size_t length, /* IN: attr's length field */
- struct attr *attr, /* IN: caller already allocated */
- uint8_t flag, /* IN: attr's flags field */
- uint8_t *startp)
+static int bgp_attr_encap(struct bgp_attr_parser_args *args)
{
- bgp_size_t total;
uint16_t tunneltype = 0;
-
- total = length + (CHECK_FLAG(flag, BGP_ATTR_FLAG_EXTLEN) ? 4 : 3);
+ struct peer *const peer = args->peer;
+ struct attr *const attr = args->attr;
+ bgp_size_t length = args->length;
+ uint8_t type = args->type;
+ uint8_t flag = args->flags;
if (!CHECK_FLAG(flag, BGP_ATTR_FLAG_TRANS)
|| !CHECK_FLAG(flag, BGP_ATTR_FLAG_OPTIONAL)) {
- zlog_info(
- "Tunnel Encap attribute flag isn't optional and transitive %d",
- flag);
- bgp_notify_send_with_data(peer, BGP_NOTIFY_UPDATE_ERR,
- BGP_NOTIFY_UPDATE_ATTR_FLAG_ERR,
- startp, total);
- return -1;
+ zlog_err("Tunnel Encap attribute flag isn't optional and transitive %d",
+ flag);
+ return bgp_attr_malformed(args, BGP_NOTIFY_UPDATE_OPT_ATTR_ERR,
+ args->total);
}
if (BGP_ATTR_ENCAP == type) {
@@ -2461,12 +2457,11 @@ static int bgp_attr_encap(uint8_t type, struct peer *peer, /* IN */
uint16_t tlv_length;
if (length < 4) {
- zlog_info(
+ zlog_err(
"Tunnel Encap attribute not long enough to contain outer T,L");
- bgp_notify_send_with_data(
- peer, BGP_NOTIFY_UPDATE_ERR,
- BGP_NOTIFY_UPDATE_OPT_ATTR_ERR, startp, total);
- return -1;
+ return bgp_attr_malformed(args,
+ BGP_NOTIFY_UPDATE_OPT_ATTR_ERR,
+ args->total);
}
tunneltype = stream_getw(BGP_INPUT(peer));
tlv_length = stream_getw(BGP_INPUT(peer));
@@ -2496,13 +2491,11 @@ static int bgp_attr_encap(uint8_t type, struct peer *peer, /* IN */
}
if (sublength > length) {
- zlog_info(
- "Tunnel Encap attribute sub-tlv length %d exceeds remaining length %d",
- sublength, length);
- bgp_notify_send_with_data(
- peer, BGP_NOTIFY_UPDATE_ERR,
- BGP_NOTIFY_UPDATE_OPT_ATTR_ERR, startp, total);
- return -1;
+ zlog_err("Tunnel Encap attribute sub-tlv length %d exceeds remaining length %d",
+ sublength, length);
+ return bgp_attr_malformed(args,
+ BGP_NOTIFY_UPDATE_OPT_ATTR_ERR,
+ args->total);
}
/* alloc and copy sub-tlv */
@@ -2550,13 +2543,10 @@ static int bgp_attr_encap(uint8_t type, struct peer *peer, /* IN */
if (length) {
/* spurious leftover data */
- zlog_info(
- "Tunnel Encap attribute length is bad: %d leftover octets",
- length);
- bgp_notify_send_with_data(peer, BGP_NOTIFY_UPDATE_ERR,
- BGP_NOTIFY_UPDATE_OPT_ATTR_ERR,
- startp, total);
- return -1;
+ zlog_err("Tunnel Encap attribute length is bad: %d leftover octets",
+ length);
+ return bgp_attr_malformed(args, BGP_NOTIFY_UPDATE_OPT_ATTR_ERR,
+ args->total);
}
return 0;
@@ -3396,8 +3386,7 @@ enum bgp_attr_parse_ret bgp_attr_parse(struct peer *peer, struct attr *attr,
case BGP_ATTR_VNC:
#endif
case BGP_ATTR_ENCAP:
- ret = bgp_attr_encap(type, peer, length, attr, flag,
- startp);
+ ret = bgp_attr_encap(&attr_args);
break;
case BGP_ATTR_PREFIX_SID:
ret = bgp_attr_prefix_sid(&attr_args);

View File

@ -7,7 +7,7 @@
Name: frr
Version: 7.5.1
Release: 7%{?checkout}%{?dist}
Release: 7%{?checkout}%{?dist}.2.alma.1
Summary: Routing daemon
License: GPLv2+
URL: http://www.frrouting.org
@ -53,6 +53,11 @@ Patch0010: 0010-moving-executables.patch
Patch0011: 0011-reload-bfd-profile.patch
Patch0012: 0012-graceful-restart.patch
Patch0013: 0013-CVE-2022-37032.patch
# Patches were taken from upstream and modified to apply cleanly:
# https://git.almalinux.org/rpms/frr/raw/commit/7599d0ae96d0c1d1f42ae62e1f885ee58ed5b0cd/SOURCES/0010-CVE-2023-38802.patch
Patch0014: 0014-bfd-profile-crash.patch
# https://gitlab.com/redhat/centos-stream/rpms/frr/-/blob/7e4d5613074b57d55f0ab900c85e20afccf1fbd4/0014-bfd-profile-crash.patch
Patch0015: 0015-CVE-2023-38802.patch
%description
FRRouting is free software that manages TCP/IP based routing protocols. It takes
@ -273,6 +278,10 @@ make check PYTHON=%{__python3}
%endif
%changelog
* Wed Sep 20 2023 Eduard Abdullin <eabdullin@almalinux.org> - 7.5.1-7.2.alma.1
- Fix CVE-2023-38802
- bfdd: remove profiles when removing bfd node
* Wed Nov 30 2022 Michal Ruprich <mruprich@redhat.com> - 7.5.1-7
- Resolves: #2128737 - out-of-bounds read in the BGP daemon may lead to information disclosure or denial of service