diff --git a/meta-networking/recipes-protocols/frr/frr/CVE-2024-55553.patch b/meta-networking/recipes-protocols/frr/frr/CVE-2024-55553.patch new file mode 100644 index 0000000000..1183b1e58b --- /dev/null +++ b/meta-networking/recipes-protocols/frr/frr/CVE-2024-55553.patch @@ -0,0 +1,304 @@ +From fc6837ad68e9724d7c15db6cb01bf9bb5beea8e5 Mon Sep 17 00:00:00 2001 +From: Donatas Abraitis +Date: Tue, 21 Jan 2025 16:07:10 +0200 +Subject: [PATCH] bgpd: Validate only affected RPKI prefixes instead of a full + RIB + +This is backport of https://github.com/FRRouting/frr/commit/b0800bfdf04b4fcf48504737ebfe4ba7f05268d3 for 8.4. + +Signed-off-by: Donatas Abraitis + +CVE: CVE-2024-55553 +Upstream-Status: Backport [https://github.com/opensourcerouting/frr/commit/cc1c66a7e8dd31c681f396f6635192c0d60a543c] + +The original patch is adjusted to fit for the current version.(8.2.2) + +Signed-off-by: Zhang Peng +--- + bgpd/bgp_rpki.c | 184 +++++++++++++++++++++--------------------------- + bgpd/bgpd.c | 4 ++ + bgpd/bgpd.h | 1 + + 3 files changed, 87 insertions(+), 102 deletions(-) + +diff --git a/bgpd/bgp_rpki.c b/bgpd/bgp_rpki.c +index 0a51269d9b..69c5f44fac 100644 +--- a/bgpd/bgp_rpki.c ++++ b/bgpd/bgp_rpki.c +@@ -67,6 +67,12 @@ static struct thread *t_rpki; + + DEFINE_MTYPE_STATIC(BGPD, BGP_RPKI_CACHE, "BGP RPKI Cache server"); + DEFINE_MTYPE_STATIC(BGPD, BGP_RPKI_CACHE_GROUP, "BGP RPKI Cache server group"); ++ ++DEFINE_MTYPE_STATIC(BGPD, BGP_RPKI_REVALIDATE, "BGP RPKI Revalidation"); ++ ++#define RPKI_VALID 1 ++#define RPKI_NOTFOUND 2 ++#define RPKI_INVALID 3 + + #define POLLING_PERIOD_DEFAULT 3600 + #define EXPIRE_INTERVAL_DEFAULT 7200 +@@ -129,7 +135,6 @@ static enum route_map_cmd_result_t route_match(void *rule, + void *object); + static void *route_match_compile(const char *arg); + static void revalidate_bgp_node(struct bgp_dest *dest, afi_t afi, safi_t safi); +-static void revalidate_all_routes(void); + + static struct rtr_mgr_config *rtr_config; + static struct list *cache_list; +@@ -339,10 +344,9 @@ inline int is_running(void) + return rtr_is_running; + } + +-static struct prefix *pfx_record_to_prefix(struct pfx_record *record) ++static void pfx_record_to_prefix(struct pfx_record *record, ++ struct prefix *prefix) + { +- struct prefix *prefix = prefix_new(); +- + prefix->prefixlen = record->min_len; + + if (record->prefix.ver == LRTR_IPV4) { +@@ -353,75 +357,102 @@ static struct prefix *pfx_record_to_prefix(struct pfx_record *record) + ipv6_addr_to_network_byte_order(record->prefix.u.addr6.addr, + prefix->u.prefix6.s6_addr32); + } +- +- return prefix; + } + +-static int bgpd_sync_callback(struct thread *thread) +-{ ++struct rpki_revalidate_prefix { + struct bgp *bgp; +- struct listnode *node; +- struct prefix *prefix; +- struct pfx_record rec; +- int retval; +- int socket = THREAD_FD(thread); ++ struct prefix prefix; ++ afi_t afi; ++ safi_t safi; ++}; + +- thread_add_read(bm->master, bgpd_sync_callback, NULL, socket, &t_rpki); ++static void rpki_revalidate_prefix(struct thread *thread) ++{ ++ struct rpki_revalidate_prefix *rrp = THREAD_ARG(thread); ++ struct bgp_dest *match, *node; + +- if (atomic_load_explicit(&rtr_update_overflow, memory_order_seq_cst)) { +- while (read(socket, &rec, sizeof(struct pfx_record)) != -1) +- ; ++ match = bgp_table_subtree_lookup(rrp->bgp->rib[rrp->afi][rrp->safi], ++ &rrp->prefix); + +- atomic_store_explicit(&rtr_update_overflow, 0, +- memory_order_seq_cst); +- revalidate_all_routes(); +- return 0; +- } ++ node = match; + +- retval = read(socket, &rec, sizeof(struct pfx_record)); +- if (retval != sizeof(struct pfx_record)) { +- RPKI_DEBUG("Could not read from socket"); +- return retval; +- } ++ while (node) { ++ if (bgp_dest_has_bgp_path_info_data(node)) { ++ revalidate_bgp_node(node, rrp->afi, rrp->safi); ++ } + +- /* RTR-Server crashed/terminated, let's handle and switch +- * to the second available RTR-Server according to preference. +- */ +- if (rec.socket && rec.socket->state == RTR_ERROR_FATAL) { +- reset(true); +- return 0; ++ node = bgp_route_next_until(node, match); + } + +- prefix = pfx_record_to_prefix(&rec); ++ XFREE(MTYPE_BGP_RPKI_REVALIDATE, rrp); ++} + +- afi_t afi = (rec.prefix.ver == LRTR_IPV4) ? AFI_IP : AFI_IP6; ++static void revalidate_single_prefix(struct prefix prefix, afi_t afi) ++{ ++ struct bgp *bgp; ++ struct listnode *node; + + for (ALL_LIST_ELEMENTS_RO(bm->bgp, node, bgp)) { + safi_t safi; + + for (safi = SAFI_UNICAST; safi < SAFI_MAX; safi++) { +- if (!bgp->rib[afi][safi]) ++ struct bgp_table *table = bgp->rib[afi][safi]; ++ struct rpki_revalidate_prefix *rrp; ++ ++ if (!table) + continue; + +- struct bgp_dest *match; +- struct bgp_dest *node; ++ rrp = XCALLOC(MTYPE_BGP_RPKI_REVALIDATE, sizeof(*rrp)); ++ rrp->bgp = bgp; ++ rrp->prefix = prefix; ++ rrp->afi = afi; ++ rrp->safi = safi; ++ thread_add_event(bm->master, rpki_revalidate_prefix, ++ rrp, 0, &bgp->t_revalidate[afi][safi]); ++ } ++ } ++} ++ ++static void bgpd_sync_callback(struct thread *thread) ++{ ++ struct prefix prefix; ++ struct pfx_record rec; ++ afi_t afi; ++ int retval; ++ ++ if (atomic_load_explicit(&rtr_update_overflow, memory_order_seq_cst)) { ++ ssize_t size = 0; + +- match = bgp_table_subtree_lookup(bgp->rib[afi][safi], +- prefix); +- node = match; ++ retval = read(rpki_sync_socket_bgpd, &rec, ++ sizeof(struct pfx_record)); ++ while (retval != -1) { ++ if (retval != sizeof(struct pfx_record)) ++ break; + +- while (node) { +- if (bgp_dest_has_bgp_path_info_data(node)) { +- revalidate_bgp_node(node, afi, safi); +- } ++ size += retval; ++ pfx_record_to_prefix(&rec, &prefix); ++ afi = (rec.prefix.ver == LRTR_IPV4) ? AFI_IP : AFI_IP6; ++ revalidate_single_prefix(prefix, afi); + +- node = bgp_route_next_until(node, match); +- } ++ retval = read(rpki_sync_socket_bgpd, &rec, ++ sizeof(struct pfx_record)); + } ++ ++ atomic_store_explicit(&rtr_update_overflow, 0, ++ memory_order_seq_cst); ++ return; + } + +- prefix_free(&prefix); +- return 0; ++ retval = read(rpki_sync_socket_bgpd, &rec, sizeof(struct pfx_record)); ++ if (retval != sizeof(struct pfx_record)) { ++ RPKI_DEBUG("Could not read from rpki_sync_socket_bgpd"); ++ return; ++ } ++ pfx_record_to_prefix(&rec, &prefix); ++ ++ afi = (rec.prefix.ver == LRTR_IPV4) ? AFI_IP : AFI_IP6; ++ ++ revalidate_single_prefix(prefix, afi); + } + + static void revalidate_bgp_node(struct bgp_dest *bgp_dest, afi_t afi, +@@ -446,63 +477,12 @@ static void revalidate_bgp_node(struct bgp_dest *bgp_dest, afi_t afi, + } + } + +-static void revalidate_all_routes(void) +-{ +- struct bgp *bgp; +- struct listnode *node; +- afi_t afi; +- safi_t safi; +- +- for (ALL_LIST_ELEMENTS_RO(bm->bgp, node, bgp)) { +- struct peer *peer; +- struct listnode *peer_listnode; +- +- for (ALL_LIST_ELEMENTS_RO(bgp->peer, peer_listnode, peer)) { +- FOREACH_AFI_SAFI (afi, safi) { +- if (!peer->afc_nego[afi][safi]) +- continue; +- +- if (!peer->bgp->rib[afi][safi]) +- continue; +- +- bgp_soft_reconfig_in(peer, afi, safi); +- } +- } +- } +-} +- +-static void rpki_connection_status_cb(const struct rtr_mgr_group *group +- __attribute__((unused)), +- enum rtr_mgr_status status, +- const struct rtr_socket *socket +- __attribute__((unused)), +- void *data __attribute__((unused))) +-{ +- struct pfx_record rec = {0}; +- int retval; +- +- if (rtr_is_stopping || +- atomic_load_explicit(&rtr_update_overflow, memory_order_seq_cst)) +- return; +- +- if (status == RTR_MGR_ERROR) +- rec.socket = socket; +- +- retval = write(rpki_sync_socket_rtr, &rec, sizeof(rec)); +- if (retval == -1 && (errno == EAGAIN || errno == EWOULDBLOCK)) +- atomic_store_explicit(&rtr_update_overflow, 1, +- memory_order_seq_cst); +- +- else if (retval != sizeof(rec)) +- RPKI_DEBUG("Could not write to rpki_sync_socket_rtr"); +-} +- + static void rpki_update_cb_sync_rtr(struct pfx_table *p __attribute__((unused)), + const struct pfx_record rec, + const bool added __attribute__((unused))) + { +- if (rtr_is_stopping +- || atomic_load_explicit(&rtr_update_overflow, memory_order_seq_cst)) ++ if (rtr_is_stopping || ++ atomic_load_explicit(&rtr_update_overflow, memory_order_seq_cst)) + return; + + int retval = +diff --git a/bgpd/bgpd.c b/bgpd/bgpd.c +index 7e528b2191..bfe96f0f01 100644 +--- a/bgpd/bgpd.c ++++ b/bgpd/bgpd.c +@@ -3579,6 +3579,10 @@ int bgp_delete(struct bgp *bgp) + + hook_call(bgp_inst_delete, bgp); + ++ THREAD_OFF(bgp->t_condition_check); ++ FOREACH_AFI_SAFI (afi, safi) ++ THREAD_OFF(bgp->t_revalidate[afi][safi]); ++ + THREAD_OFF(bgp->t_startup); + THREAD_OFF(bgp->t_maxmed_onstartup); + THREAD_OFF(bgp->t_update_delay); +diff --git a/bgpd/bgpd.h b/bgpd/bgpd.h +index 8b93c450e8..45db4752f4 100644 +--- a/bgpd/bgpd.h ++++ b/bgpd/bgpd.h +@@ -426,6 +426,7 @@ struct bgp { + /* BGP update delay on startup */ + struct thread *t_update_delay; + struct thread *t_establish_wait; ++ struct thread *t_revalidate[AFI_MAX][SAFI_MAX]; + uint8_t update_delay_over; + uint8_t main_zebra_update_hold; + uint8_t main_peers_update_hold; +-- +2.35.5 + 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 facc655e29..975607f5af 100644 --- a/meta-networking/recipes-protocols/frr/frr_8.2.2.bb +++ b/meta-networking/recipes-protocols/frr/frr_8.2.2.bb @@ -34,6 +34,7 @@ SRC_URI = "git://github.com/FRRouting/frr.git;protocol=https;branch=stable/8.2 \ file://CVE-2024-31950.patch \ file://CVE-2024-31951.patch \ file://CVE-2024-31948.patch \ + file://CVE-2024-55553.patch \ " SRCREV = "79188bf710e92acf42fb5b9b0a2e9593a5ee9b05"