diff --git a/.frr.metadata b/.frr.metadata index 3464e39..48fa4ae 100644 --- a/.frr.metadata +++ b/.frr.metadata @@ -1,2 +1 @@ 467835eb73a6018948fd667663ce68282cf6d16b SOURCES/frr-8.3.1.tar.gz -e25979fad0e873cd0196e528cae570ba18c11a8f SOURCES/frr.if diff --git a/.gitignore b/.gitignore index 9268eb3..00c04c8 100644 --- a/.gitignore +++ b/.gitignore @@ -1,2 +1 @@ SOURCES/frr-8.3.1.tar.gz -SOURCES/frr.if diff --git a/SOURCES/0004-fips-mode.patch b/SOURCES/0004-fips-mode.patch index e8efeb7..51f9ed3 100644 --- a/SOURCES/0004-fips-mode.patch +++ b/SOURCES/0004-fips-mode.patch @@ -101,3 +101,15 @@ index 5bb81ef..02a09ef 100644 nb_cli_enqueue_change(vty, "./authentication-scheme/mode", NB_OP_MODIFY, strmatch(mode, "md5") ? "md5" : "plain-text"); if (strmatch(mode, "md5")) +diff --git a/lib/zebra.h b/lib/zebra.h +index 53ae5b4..930307f 100644 +--- a/lib/zebra.h ++++ b/lib/zebra.h +@@ -114,6 +114,7 @@ + #ifdef CRYPTO_OPENSSL + #include + #include ++#include + #endif + + #include "openbsd-tree.h" diff --git a/SOURCES/0009-CVE-2022-36440-40302.patch b/SOURCES/0009-CVE-2022-36440-40302.patch new file mode 100644 index 0000000..08de573 --- /dev/null +++ b/SOURCES/0009-CVE-2022-36440-40302.patch @@ -0,0 +1,59 @@ +From 3e46b43e3788f0f87bae56a86b54d412b4710286 Mon Sep 17 00:00:00 2001 +From: Donald Sharp +Date: Fri, 30 Sep 2022 08:51:45 -0400 +Subject: [PATCH] bgpd: Ensure FRR has enough data to read 2 bytes in + peek_for_as4_capability + +In peek_for_as4_capability the code is checking that the +stream has at least 2 bytes to read ( the opt_type and the +opt_length ). However if BGP_OPEN_EXT_OPT_PARAMS_CAPABLE(peer) +is configured then FRR is reading 3 bytes. Which is not good +since the packet could be badly formated. Ensure that +FRR has the appropriate data length to read the data. + +Signed-off-by: Donald Sharp +--- + bgpd/bgp_open.c | 27 +++++++++++++++++++++------ + 1 file changed, 21 insertions(+), 6 deletions(-) + +diff --git a/bgpd/bgp_open.c b/bgpd/bgp_open.c +index 7248f034a5a..a760a7ca013 100644 +--- a/bgpd/bgp_open.c ++++ b/bgpd/bgp_open.c +@@ -1185,15 +1185,30 @@ as_t peek_for_as4_capability(struct peer *peer, uint16_t length) + uint8_t opt_type; + uint16_t opt_length; + +- /* Check the length. */ +- if (stream_get_getp(s) + 2 > end) ++ /* Ensure we can read the option type */ ++ if (stream_get_getp(s) + 1 > end) + goto end; + +- /* Fetch option type and length. */ ++ /* Fetch the option type */ + opt_type = stream_getc(s); +- opt_length = BGP_OPEN_EXT_OPT_PARAMS_CAPABLE(peer) +- ? stream_getw(s) +- : stream_getc(s); ++ ++ /* ++ * Check the length and fetch the opt_length ++ * If the peer is BGP_OPEN_EXT_OPT_PARAMS_CAPABLE(peer) ++ * then we do a getw which is 2 bytes. So we need to ++ * ensure that we can read that as well ++ */ ++ if (BGP_OPEN_EXT_OPT_PARAMS_CAPABLE(peer)) { ++ if (stream_get_getp(s) + 2 > end) ++ goto end; ++ ++ opt_length = stream_getw(s); ++ } else { ++ if (stream_get_getp(s) + 1 > end) ++ goto end; ++ ++ opt_length = stream_getc(s); ++ } + + /* Option length check. */ + if (stream_get_getp(s) + opt_length > end) diff --git a/SOURCES/0010-CVE-2022-43681.patch b/SOURCES/0010-CVE-2022-43681.patch new file mode 100644 index 0000000..73fcfc3 --- /dev/null +++ b/SOURCES/0010-CVE-2022-43681.patch @@ -0,0 +1,47 @@ +From 766eec1b7accffe2c04a5c9ebb14e9f487bb9f78 Mon Sep 17 00:00:00 2001 +From: Donald Sharp +Date: Wed, 2 Nov 2022 13:24:48 -0400 +Subject: [PATCH] bgpd: Ensure that bgp open message stream has enough data to + read + +If a operator receives an invalid packet that is of insufficient size +then it is possible for BGP to assert during reading of the packet +instead of gracefully resetting the connection with the peer. + +Signed-off-by: Donald Sharp +--- + bgpd/bgp_packet.c | 19 +++++++++++++++++++ + 1 file changed, 19 insertions(+) + +diff --git a/bgpd/bgp_packet.c b/bgpd/bgp_packet.c +index 769f9613da8..72d6a923175 100644 +--- a/bgpd/bgp_packet.c ++++ b/bgpd/bgp_packet.c +@@ -1386,8 +1386,27 @@ static int bgp_open_receive(struct peer *peer, bgp_size_t size) + || CHECK_FLAG(peer->flags, PEER_FLAG_EXTENDED_OPT_PARAMS)) { + uint8_t opttype; + ++ if (STREAM_READABLE(peer->curr) < 1) { ++ flog_err( ++ EC_BGP_PKT_OPEN, ++ "%s: stream does not have enough bytes for extended optional parameters", ++ peer->host); ++ bgp_notify_send(peer, BGP_NOTIFY_OPEN_ERR, ++ BGP_NOTIFY_OPEN_MALFORMED_ATTR); ++ return BGP_Stop; ++ } ++ + opttype = stream_getc(peer->curr); + if (opttype == BGP_OPEN_NON_EXT_OPT_TYPE_EXTENDED_LENGTH) { ++ if (STREAM_READABLE(peer->curr) < 2) { ++ flog_err( ++ EC_BGP_PKT_OPEN, ++ "%s: stream does not have enough bytes to read the extended optional parameters optlen", ++ peer->host); ++ bgp_notify_send(peer, BGP_NOTIFY_OPEN_ERR, ++ BGP_NOTIFY_OPEN_MALFORMED_ATTR); ++ return BGP_Stop; ++ } + optlen = stream_getw(peer->curr); + SET_FLAG(peer->sflags, + PEER_STATUS_EXT_OPT_PARAMS_LENGTH); diff --git a/SOURCES/0011-CVE-2022-40318.patch b/SOURCES/0011-CVE-2022-40318.patch new file mode 100644 index 0000000..e4dadfb --- /dev/null +++ b/SOURCES/0011-CVE-2022-40318.patch @@ -0,0 +1,70 @@ +From 1117baca3c592877a4d8a13ed6a1d9bd83977487 Mon Sep 17 00:00:00 2001 +From: Donald Sharp +Date: Fri, 30 Sep 2022 08:57:43 -0400 +Subject: [PATCH] bgpd: Ensure FRR has enough data to read 2 bytes in + bgp_open_option_parse + +In bgp_open_option_parse the code is checking that the +stream has at least 2 bytes to read ( the opt_type and +the opt_length). However if BGP_OPEN_EXT_OPT_PARAMS_CAPABLE(peer) +is configured then FRR is reading 3 bytes. Which is not good +since the packet could be badly formateed. Ensure that +FRR has the appropriate data length to read the data. + +Signed-off-by: Donald Sharp +--- + bgpd/bgp_open.c | 35 ++++++++++++++++++++++++++++------- + 1 file changed, 28 insertions(+), 7 deletions(-) + +diff --git a/bgpd/bgp_open.c b/bgpd/bgp_open.c +index a760a7ca013..d1667fac261 100644 +--- a/bgpd/bgp_open.c ++++ b/bgpd/bgp_open.c +@@ -1278,19 +1278,40 @@ int bgp_open_option_parse(struct peer *peer, uint16_t length, + uint8_t opt_type; + uint16_t opt_length; + +- /* Must have at least an OPEN option header */ +- if (STREAM_READABLE(s) < 2) { ++ /* ++ * Check that we can read the opt_type and fetch it ++ */ ++ if (STREAM_READABLE(s) < 1) { + zlog_info("%s Option length error", peer->host); + bgp_notify_send(peer, BGP_NOTIFY_OPEN_ERR, + BGP_NOTIFY_OPEN_MALFORMED_ATTR); + return -1; + } +- +- /* Fetch option type and length. */ + opt_type = stream_getc(s); +- opt_length = BGP_OPEN_EXT_OPT_PARAMS_CAPABLE(peer) +- ? stream_getw(s) +- : stream_getc(s); ++ ++ /* ++ * Check the length of the stream to ensure that ++ * FRR can properly read the opt_length. Then read it ++ */ ++ if (BGP_OPEN_EXT_OPT_PARAMS_CAPABLE(peer)) { ++ if (STREAM_READABLE(s) < 2) { ++ zlog_info("%s Option length error", peer->host); ++ bgp_notify_send(peer, BGP_NOTIFY_OPEN_ERR, ++ BGP_NOTIFY_OPEN_MALFORMED_ATTR); ++ return -1; ++ } ++ ++ opt_length = stream_getw(s); ++ } else { ++ if (STREAM_READABLE(s) < 1) { ++ zlog_info("%s Option length error", peer->host); ++ bgp_notify_send(peer, BGP_NOTIFY_OPEN_ERR, ++ BGP_NOTIFY_OPEN_MALFORMED_ATTR); ++ return -1; ++ } ++ ++ opt_length = stream_getc(s); ++ } + + /* Option length check. */ + if (STREAM_READABLE(s) < opt_length) { diff --git a/SOURCES/0012-bfd-not-working-in-vrf.patch b/SOURCES/0012-bfd-not-working-in-vrf.patch new file mode 100644 index 0000000..6ee8490 --- /dev/null +++ b/SOURCES/0012-bfd-not-working-in-vrf.patch @@ -0,0 +1,255 @@ +From edc3f63167fd95e4e70287743c9b252415c9336e Mon Sep 17 00:00:00 2001 +From: Philippe Guibert +Date: Thu, 7 Jul 2022 14:33:48 +0200 +Subject: [PATCH] bfdd: allow l3vrf bfd sessions without udp leaking + +Until now, when in vrf-lite mode, the BFD implementation +creates a single UDP socket and relies on the following +sysctl value to 1: + +echo 1 > /proc/sys/net/ipv4/udp_l3mdev_accept + +With this setting, the incoming BFD packets from a given +vrf, would leak to the default vrf, and would match the +UDP socket. + +The drawback of this solution is that udp packets received +on a given vrf may leak to an other vrf. This may be a +security concern. + +The commit addresses this issue by avoiding this leak +mechanism. An UDP socket is created for each vrf, and each +socket uses new setsockopt option: SO_REUSEADDR + SO_REUSEPORT. + +With this option, the incoming UDP packets are distributed on +the available sockets. The impact of those options with l3mdev +devices is unknown. It has been observed that this option is not +needed, until the default vrf sockets are created. + +To ensure the BFD packets are correctly routed to the appropriate +socket, a BPF filter has been put in place and attached to the +sockets : SO_ATTACH_REUSEPORT_CBPF. This option adds a criterium +to force the packet to choose a given socket. If initial criteria +from the default distribution algorithm were not good, at least +two sockets would be available, and the CBPF would force the +selection to the same socket. This would come to the situation +where an incoming packet would be processed on a different vrf. + +The bpf code is the following one: + +struct sock_filter code[] = { + { BPF_RET | BPF_K, 0, 0, 0 }, +}; + +struct sock_fprog p = { + .len = sizeof(code)/sizeof(struct sock_filter), + .filter = code, +}; + +if (setsockopt(sd, SOL_SOCKET, SO_ATTACH_REUSEPORT_CBPF, &p, sizeof(p))) { + zlog_warn("unable to set SO_ATTACH_REUSEPORT_CBPF on socket: %s", + strerror(errno)); + return -1; +} + +Some tests have been done with by creating vrf contexts, and by using +the below vtysh configuration: + +ip route 2.2.2.2/32 10.126.0.2 +vrf vrf2 + ip route 2.2.2.2/32 10.126.0.2 +! +interface ntfp2 + ip address 10.126.0.1/24 +! +interface ntfp3 vrf vrf4 + ip address 10.126.0.1/24 +! +interface ntfp2 vrf vrf1 + ip address 10.126.0.1/24 +! +interface ntfp2.100 vrf vrf2 + ip address 10.126.0.1/24 +! +interface ntfp2.200 vrf vrf3 + ip address 10.126.0.1/24 +! +line vty +! +bfd + peer 10.126.0.2 vrf vrf2 + ! + peer 10.126.0.2 vrf vrf3 + ! + peer 10.126.0.2 + ! + peer 10.126.0.2 vrf vrf4 + ! + peer 2.2.2.2 multihop local-address 1.1.1.1 + ! + peer 2.2.2.2 multihop local-address 1.1.1.1 vrf vrf2 + transmit-interval 1500 + receive-interval 1500 + ! + +The results showed no issue related to packets received by +the wrong vrf. Even changing the udp_l3mdev_accept flag to +1 did not change the test results. + +Signed-off-by: Philippe Guibert +--- + bfdd/bfd.c | 66 +++++++++++++++++++++++------------------------ + bfdd/bfd_packet.c | 45 ++++++++++++++++++++++++++++++++ + 2 files changed, 77 insertions(+), 34 deletions(-) + +diff --git a/bfdd/bfd.c b/bfdd/bfd.c +index 483beb1b17c..a1619263588 100644 +--- a/bfdd/bfd.c ++++ b/bfdd/bfd.c +@@ -1950,40 +1950,38 @@ static int bfd_vrf_enable(struct vrf *vrf) + if (bglobal.debug_zebra) + zlog_debug("VRF enable add %s id %u", vrf->name, vrf->vrf_id); + +- if (vrf->vrf_id == VRF_DEFAULT || +- vrf_get_backend() == VRF_BACKEND_NETNS) { +- if (!bvrf->bg_shop) +- bvrf->bg_shop = bp_udp_shop(vrf); +- if (!bvrf->bg_mhop) +- bvrf->bg_mhop = bp_udp_mhop(vrf); +- if (!bvrf->bg_shop6) +- bvrf->bg_shop6 = bp_udp6_shop(vrf); +- if (!bvrf->bg_mhop6) +- bvrf->bg_mhop6 = bp_udp6_mhop(vrf); +- if (!bvrf->bg_echo) +- bvrf->bg_echo = bp_echo_socket(vrf); +- if (!bvrf->bg_echov6) +- bvrf->bg_echov6 = bp_echov6_socket(vrf); +- +- if (!bvrf->bg_ev[0] && bvrf->bg_shop != -1) +- thread_add_read(master, bfd_recv_cb, bvrf, +- bvrf->bg_shop, &bvrf->bg_ev[0]); +- if (!bvrf->bg_ev[1] && bvrf->bg_mhop != -1) +- thread_add_read(master, bfd_recv_cb, bvrf, +- bvrf->bg_mhop, &bvrf->bg_ev[1]); +- if (!bvrf->bg_ev[2] && bvrf->bg_shop6 != -1) +- thread_add_read(master, bfd_recv_cb, bvrf, +- bvrf->bg_shop6, &bvrf->bg_ev[2]); +- if (!bvrf->bg_ev[3] && bvrf->bg_mhop6 != -1) +- thread_add_read(master, bfd_recv_cb, bvrf, +- bvrf->bg_mhop6, &bvrf->bg_ev[3]); +- if (!bvrf->bg_ev[4] && bvrf->bg_echo != -1) +- thread_add_read(master, bfd_recv_cb, bvrf, +- bvrf->bg_echo, &bvrf->bg_ev[4]); +- if (!bvrf->bg_ev[5] && bvrf->bg_echov6 != -1) +- thread_add_read(master, bfd_recv_cb, bvrf, +- bvrf->bg_echov6, &bvrf->bg_ev[5]); +- } ++ if (!bvrf->bg_shop) ++ bvrf->bg_shop = bp_udp_shop(vrf); ++ if (!bvrf->bg_mhop) ++ bvrf->bg_mhop = bp_udp_mhop(vrf); ++ if (!bvrf->bg_shop6) ++ bvrf->bg_shop6 = bp_udp6_shop(vrf); ++ if (!bvrf->bg_mhop6) ++ bvrf->bg_mhop6 = bp_udp6_mhop(vrf); ++ if (!bvrf->bg_echo) ++ bvrf->bg_echo = bp_echo_socket(vrf); ++ if (!bvrf->bg_echov6) ++ bvrf->bg_echov6 = bp_echov6_socket(vrf); ++ ++ if (!bvrf->bg_ev[0] && bvrf->bg_shop != -1) ++ thread_add_read(master, bfd_recv_cb, bvrf, bvrf->bg_shop, ++ &bvrf->bg_ev[0]); ++ if (!bvrf->bg_ev[1] && bvrf->bg_mhop != -1) ++ thread_add_read(master, bfd_recv_cb, bvrf, bvrf->bg_mhop, ++ &bvrf->bg_ev[1]); ++ if (!bvrf->bg_ev[2] && bvrf->bg_shop6 != -1) ++ thread_add_read(master, bfd_recv_cb, bvrf, bvrf->bg_shop6, ++ &bvrf->bg_ev[2]); ++ if (!bvrf->bg_ev[3] && bvrf->bg_mhop6 != -1) ++ thread_add_read(master, bfd_recv_cb, bvrf, bvrf->bg_mhop6, ++ &bvrf->bg_ev[3]); ++ if (!bvrf->bg_ev[4] && bvrf->bg_echo != -1) ++ thread_add_read(master, bfd_recv_cb, bvrf, bvrf->bg_echo, ++ &bvrf->bg_ev[4]); ++ if (!bvrf->bg_ev[5] && bvrf->bg_echov6 != -1) ++ thread_add_read(master, bfd_recv_cb, bvrf, bvrf->bg_echov6, ++ &bvrf->bg_ev[5]); ++ + if (vrf->vrf_id != VRF_DEFAULT) { + bfdd_zclient_register(vrf->vrf_id); + bfdd_sessions_enable_vrf(vrf); +diff --git a/bfdd/bfd_packet.c b/bfdd/bfd_packet.c +index d34d6427628..054a9bfbf21 100644 +--- a/bfdd/bfd_packet.c ++++ b/bfdd/bfd_packet.c +@@ -876,6 +876,14 @@ void bfd_recv_cb(struct thread *t) + "no session found"); + return; + } ++ /* ++ * We may have a situation where received packet is on wrong vrf ++ */ ++ if (bfd && bfd->vrf && bfd->vrf != bvrf->vrf) { ++ cp_debug(is_mhop, &peer, &local, ifindex, vrfid, ++ "wrong vrfid."); ++ return; ++ } + + /* Ensure that existing good sessions are not overridden. */ + if (!cp->discrs.remote_discr && bfd->ses_state != PTM_BFD_DOWN && +@@ -1208,10 +1216,41 @@ int bp_set_tos(int sd, uint8_t value) + return 0; + } + ++static bool bp_set_reuse_addr(int sd) ++{ ++ int one = 1; ++ ++ if (setsockopt(sd, SOL_SOCKET, SO_REUSEADDR, &one, sizeof(one)) == -1) { ++ zlog_warn("set-reuse-addr: setsockopt(SO_REUSEADDR, %d): %s", ++ one, strerror(errno)); ++ return false; ++ } ++ return true; ++} ++ ++static bool bp_set_reuse_port(int sd) ++{ ++ int one = 1; ++ ++ if (setsockopt(sd, SOL_SOCKET, SO_REUSEPORT, &one, sizeof(one)) == -1) { ++ zlog_warn("set-reuse-port: setsockopt(SO_REUSEPORT, %d): %s", ++ one, strerror(errno)); ++ return false; ++ } ++ return true; ++} ++ ++ + static void bp_set_ipopts(int sd) + { + int rcvttl = BFD_RCV_TTL_VAL; + ++ if (!bp_set_reuse_addr(sd)) ++ zlog_fatal("set-reuse-addr: failed"); ++ ++ if (!bp_set_reuse_port(sd)) ++ zlog_fatal("set-reuse-port: failed"); ++ + if (bp_set_ttl(sd, BFD_TTL_VAL) != 0) + zlog_fatal("set-ipopts: TTL configuration failed"); + +@@ -1453,6 +1492,12 @@ static void bp_set_ipv6opts(int sd) + int ipv6_pktinfo = BFD_IPV6_PKT_INFO_VAL; + int ipv6_only = BFD_IPV6_ONLY_VAL; + ++ if (!bp_set_reuse_addr(sd)) ++ zlog_fatal("set-reuse-addr: failed"); ++ ++ if (!bp_set_reuse_port(sd)) ++ zlog_fatal("set-reuse-port: failed"); ++ + if (bp_set_ttlv6(sd, BFD_TTL_VAL) == -1) + zlog_fatal( + "set-ipv6opts: setsockopt(IPV6_UNICAST_HOPS, %d): %s", diff --git a/SOURCES/CVE-2023-38802.patch b/SOURCES/CVE-2023-38802.patch new file mode 100644 index 0000000..728db32 --- /dev/null +++ b/SOURCES/CVE-2023-38802.patch @@ -0,0 +1,129 @@ +From 46817adab03802355c3cce7b753c7a735bdcc5ae Mon Sep 17 00:00:00 2001 +From: Donatas Abraitis +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 +(cherry picked from commit bcb6b58d9530173df41d3a3cbc4c600ee0b4b186) +--- + 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 058fae23cbd..1c0803cfd8e 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); diff --git a/SOURCES/frr.if b/SOURCES/frr.if new file mode 100644 index 0000000..8dbabba --- /dev/null +++ b/SOURCES/frr.if @@ -0,0 +1,214 @@ +## policy for frr + +######################################## +## +## Execute frr_exec_t in the frr domain. +## +## +## +## Domain allowed to transition. +## +## +# +interface(`frr_domtrans',` + gen_require(` + type frr_t, frr_exec_t; + ') + + corecmd_search_bin($1) + domtrans_pattern($1, frr_exec_t, frr_t) +') + +###################################### +## +## Execute frr in the caller domain. +## +## +## +## Domain allowed access. +## +## +# +interface(`frr_exec',` + gen_require(` + type frr_exec_t; + ') + + corecmd_search_bin($1) + can_exec($1, frr_exec_t) +') + +######################################## +## +## Read frr's log files. +## +## +## +## Domain allowed access. +## +## +## +# +interface(`frr_read_log',` + gen_require(` + type frr_log_t; + ') + + read_files_pattern($1, frr_log_t, frr_log_t) + optional_policy(` + logging_search_logs($1) + ') +') + +######################################## +## +## Append to frr log files. +## +## +## +## Domain allowed access. +## +## +# +interface(`frr_append_log',` + gen_require(` + type frr_log_t; + ') + + append_files_pattern($1, frr_log_t, frr_log_t) + optional_policy(` + logging_search_logs($1) + ') +') + +######################################## +## +## Manage frr log files +## +## +## +## Domain allowed access. +## +## +# +interface(`frr_manage_log',` + gen_require(` + type frr_log_t; + ') + + manage_dirs_pattern($1, frr_log_t, frr_log_t) + manage_files_pattern($1, frr_log_t, frr_log_t) + manage_lnk_files_pattern($1, frr_log_t, frr_log_t) + optional_policy(` + logging_search_logs($1) + ') +') + +######################################## +## +## Read frr PID files. +## +## +## +## Domain allowed access. +## +## +# +interface(`frr_read_pid_files',` + gen_require(` + type frr_var_run_t; + ') + + files_search_pids($1) + read_files_pattern($1, frr_var_run_t, frr_var_run_t) +') + +######################################## +## +## All of the rules required to administrate +## an frr environment +## +## +## +## Domain allowed access. +## +## +# +interface(`frr_admin',` + gen_require(` + type frr_t; + type frr_log_t; + type frr_var_run_t; + ') + + allow $1 frr_t:process { signal_perms }; + ps_process_pattern($1, frr_t) + + tunable_policy(`deny_ptrace',`',` + allow $1 frr_t:process ptrace; + ') + + admin_pattern($1, frr_log_t) + + files_search_pids($1) + admin_pattern($1, frr_var_run_t) + optional_policy(` + logging_search_logs($1) + ') + optional_policy(` + systemd_passwd_agent_exec($1) + systemd_read_fifo_file_passwd_run($1) + ') +') + +######################################## +# +# Interface compatibility blocks +# +# The following definitions ensure compatibility with distribution policy +# versions that do not contain given interfaces (epel, or older Fedora +# releases). +# Each block tests for existence of given interface and defines it if needed. +# + +###################################### +## +## Watch ifconfig_var_run_t directories +## +## +## +## Domain allowed access. +## +## +# +ifndef(`sysnet_watch_ifconfig_run',` + interface(`sysnet_watch_ifconfig_run',` + gen_require(` + type ifconfig_var_run_t; + ') + + watch_dirs_pattern($1, ifconfig_var_run_t, ifconfig_var_run_t) + ') +') + +######################################## +## +## Read ifconfig_var_run_t files and link files +## +## +## +## Domain allowed access. +## +## +# +ifndef(`sysnet_read_ifconfig_run',` + interface(`sysnet_read_ifconfig_run',` + gen_require(` + type ifconfig_var_run_t; + ') + + list_dirs_pattern($1, ifconfig_var_run_t, ifconfig_var_run_t) + read_files_pattern($1, ifconfig_var_run_t, ifconfig_var_run_t) + read_lnk_files_pattern($1, ifconfig_var_run_t, ifconfig_var_run_t) + ') +') diff --git a/SOURCES/frr.te b/SOURCES/frr.te index 0178c2a..d9d1169 100644 --- a/SOURCES/frr.te +++ b/SOURCES/frr.te @@ -31,9 +31,9 @@ files_pid_file(frr_var_run_t) # # frr local policy # -allow frr_t self:capability { chown dac_override dac_read_search kill net_bind_service net_raw setgid setuid net_admin }; +allow frr_t self:capability { chown dac_override dac_read_search kill net_bind_service net_raw setgid setuid net_admin sys_admin }; allow frr_t self:netlink_route_socket rw_netlink_socket_perms; -allow frr_t self:packet_socket create; +allow frr_t self:packet_socket create_socket_perms; allow frr_t self:process { setcap setpgid }; allow frr_t self:rawip_socket create_socket_perms; allow frr_t self:tcp_socket { connect connected_stream_socket_perms }; @@ -95,6 +95,10 @@ domain_use_interactive_fds(frr_t) fs_read_nsfs_files(frr_t) sysnet_exec_ifconfig(frr_t) +sysnet_read_ifconfig_run(frr_t) +sysnet_watch_ifconfig_run(frr_t) + +ipsec_domtrans_mgmt(frr_t) userdom_read_admin_home_files(frr_t) diff --git a/SPECS/frr.spec b/SPECS/frr.spec index 31d9bee..c8cf6b1 100644 --- a/SPECS/frr.spec +++ b/SPECS/frr.spec @@ -7,7 +7,7 @@ Name: frr Version: 8.3.1 -Release: 5%{?checkout}%{?dist}.2.alma +Release: 11%{?checkout}%{?dist}.alma.1 Summary: Routing daemon License: GPLv2+ URL: http://www.frrouting.org @@ -71,11 +71,13 @@ Patch0005: 0005-ospf-api.patch Patch0006: 0006-graceful-restart.patch Patch0007: 0007-cve-2022-37032.patch Patch0008: 0008-frr-non-root-user.patch +Patch0009: 0009-CVE-2022-36440-40302.patch +Patch0010: 0010-CVE-2022-43681.patch +Patch0011: 0011-CVE-2022-40318.patch +Patch0012: 0012-bfd-not-working-in-vrf.patch # Patches were taken from upstream and modified to apply cleanly: -# https://gitlab.com/redhat/centos-stream/rpms/frr/-/commit/4fbe36d12fc27a0f8eada5c14a4ab434ab0b9af8 -Patch0009: 0009-bfd-not-working-in-vrf.patch -# https://github.com/FRRouting/frr/pull/14290/commits/bcb6b58d9530173df41d3a3cbc4c600ee0b4b186 -Patch0010: 0010-CVE-2023-38802.patch +# https://gitlab.com/redhat/centos-stream/rpms/frr/-/commit/0b762a19a765d1a7e7f8e0e7caac1706f7ca02d1 +Patch0013: CVE-2023-38802.patch %description FRRouting is free software that manages TCP/IP based routing protocols. It takes @@ -281,11 +283,26 @@ make check PYTHON=%{__python3} %endif %changelog -* Tue Sep 19 2023 Eduard Abdullin - 8.3.1-5.2.alma -- Fix CVE-2023-38802 +* Tue Nov 07 2023 Eduard Abdullin - 8.3.1-11.alma.1 +- Related: #2216912 - adding sys_admin to capabilities -* Wed Aug 02 2023 Eduard Abdullin - 8.3.1-5.1.alma -- Apply 0009-bfd-not-working-in-vrf.patch +* Thu Aug 10 2023 Michal Ruprich - 8.3.1-10 +- Related: #2216912 - adding sys_admin to capabilities + +* Tue Aug 08 2023 Michal Ruprich - 8.3.1-9 +- Resolves: #2215346 - frr policy does not allow the execution of /usr/sbin/ipsec + +* Mon Aug 07 2023 Michal Ruprich - 8.3.1-8 +- Resolves: #2216912 - SELinux is preventing FRR-Zebra to access to network namespaces + +* Wed Jun 07 2023 Michal Ruprich - 8.3.1-7 +- Resolves: #2168855 - BFD not working through VRF + +* Tue May 23 2023 Michal Ruprich - 8.3.1-6 +- Resolves: #2184870 - Reachable assertion in peek_for_as4_capability function +- Resolves: #2196795 - denial of service by crafting a BGP OPEN message with an option of type 0xff +- Resolves: #2196796 - denial of service by crafting a BGP OPEN message with an option of type 0xff +- Resolves: #2196794 - out-of-bounds read exists in the BGP daemon of FRRouting * Mon Nov 28 2022 Michal Ruprich - 8.3.1-5 - Resolves: #2147522 - It is not possible to run FRR as a non-root user