diff options
| -rw-r--r-- | meta-networking/recipes-protocols/frr/frr/CVE-2024-55553.patch | 304 | ||||
| -rw-r--r-- | meta-networking/recipes-protocols/frr/frr_8.2.2.bb | 1 |
2 files changed, 305 insertions, 0 deletions
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 @@ | |||
| 1 | From fc6837ad68e9724d7c15db6cb01bf9bb5beea8e5 Mon Sep 17 00:00:00 2001 | ||
| 2 | From: Donatas Abraitis <donatas@opensourcerouting.org> | ||
| 3 | Date: Tue, 21 Jan 2025 16:07:10 +0200 | ||
| 4 | Subject: [PATCH] bgpd: Validate only affected RPKI prefixes instead of a full | ||
| 5 | RIB | ||
| 6 | |||
| 7 | This is backport of https://github.com/FRRouting/frr/commit/b0800bfdf04b4fcf48504737ebfe4ba7f05268d3 for 8.4. | ||
| 8 | |||
| 9 | Signed-off-by: Donatas Abraitis <donatas@opensourcerouting.org> | ||
| 10 | |||
| 11 | CVE: CVE-2024-55553 | ||
| 12 | Upstream-Status: Backport [https://github.com/opensourcerouting/frr/commit/cc1c66a7e8dd31c681f396f6635192c0d60a543c] | ||
| 13 | |||
| 14 | The original patch is adjusted to fit for the current version.(8.2.2) | ||
| 15 | |||
| 16 | Signed-off-by: Zhang Peng <peng.zhang1.cn@windriver.com> | ||
| 17 | --- | ||
| 18 | bgpd/bgp_rpki.c | 184 +++++++++++++++++++++--------------------------- | ||
| 19 | bgpd/bgpd.c | 4 ++ | ||
| 20 | bgpd/bgpd.h | 1 + | ||
| 21 | 3 files changed, 87 insertions(+), 102 deletions(-) | ||
| 22 | |||
| 23 | diff --git a/bgpd/bgp_rpki.c b/bgpd/bgp_rpki.c | ||
| 24 | index 0a51269d9b..69c5f44fac 100644 | ||
| 25 | --- a/bgpd/bgp_rpki.c | ||
| 26 | +++ b/bgpd/bgp_rpki.c | ||
| 27 | @@ -67,6 +67,12 @@ static struct thread *t_rpki; | ||
| 28 | |||
| 29 | DEFINE_MTYPE_STATIC(BGPD, BGP_RPKI_CACHE, "BGP RPKI Cache server"); | ||
| 30 | DEFINE_MTYPE_STATIC(BGPD, BGP_RPKI_CACHE_GROUP, "BGP RPKI Cache server group"); | ||
| 31 | + | ||
| 32 | +DEFINE_MTYPE_STATIC(BGPD, BGP_RPKI_REVALIDATE, "BGP RPKI Revalidation"); | ||
| 33 | + | ||
| 34 | +#define RPKI_VALID 1 | ||
| 35 | +#define RPKI_NOTFOUND 2 | ||
| 36 | +#define RPKI_INVALID 3 | ||
| 37 | |||
| 38 | #define POLLING_PERIOD_DEFAULT 3600 | ||
| 39 | #define EXPIRE_INTERVAL_DEFAULT 7200 | ||
| 40 | @@ -129,7 +135,6 @@ static enum route_map_cmd_result_t route_match(void *rule, | ||
| 41 | void *object); | ||
| 42 | static void *route_match_compile(const char *arg); | ||
| 43 | static void revalidate_bgp_node(struct bgp_dest *dest, afi_t afi, safi_t safi); | ||
| 44 | -static void revalidate_all_routes(void); | ||
| 45 | |||
| 46 | static struct rtr_mgr_config *rtr_config; | ||
| 47 | static struct list *cache_list; | ||
| 48 | @@ -339,10 +344,9 @@ inline int is_running(void) | ||
| 49 | return rtr_is_running; | ||
| 50 | } | ||
| 51 | |||
| 52 | -static struct prefix *pfx_record_to_prefix(struct pfx_record *record) | ||
| 53 | +static void pfx_record_to_prefix(struct pfx_record *record, | ||
| 54 | + struct prefix *prefix) | ||
| 55 | { | ||
| 56 | - struct prefix *prefix = prefix_new(); | ||
| 57 | - | ||
| 58 | prefix->prefixlen = record->min_len; | ||
| 59 | |||
| 60 | if (record->prefix.ver == LRTR_IPV4) { | ||
| 61 | @@ -353,75 +357,102 @@ static struct prefix *pfx_record_to_prefix(struct pfx_record *record) | ||
| 62 | ipv6_addr_to_network_byte_order(record->prefix.u.addr6.addr, | ||
| 63 | prefix->u.prefix6.s6_addr32); | ||
| 64 | } | ||
| 65 | - | ||
| 66 | - return prefix; | ||
| 67 | } | ||
| 68 | |||
| 69 | -static int bgpd_sync_callback(struct thread *thread) | ||
| 70 | -{ | ||
| 71 | +struct rpki_revalidate_prefix { | ||
| 72 | struct bgp *bgp; | ||
| 73 | - struct listnode *node; | ||
| 74 | - struct prefix *prefix; | ||
| 75 | - struct pfx_record rec; | ||
| 76 | - int retval; | ||
| 77 | - int socket = THREAD_FD(thread); | ||
| 78 | + struct prefix prefix; | ||
| 79 | + afi_t afi; | ||
| 80 | + safi_t safi; | ||
| 81 | +}; | ||
| 82 | |||
| 83 | - thread_add_read(bm->master, bgpd_sync_callback, NULL, socket, &t_rpki); | ||
| 84 | +static void rpki_revalidate_prefix(struct thread *thread) | ||
| 85 | +{ | ||
| 86 | + struct rpki_revalidate_prefix *rrp = THREAD_ARG(thread); | ||
| 87 | + struct bgp_dest *match, *node; | ||
| 88 | |||
| 89 | - if (atomic_load_explicit(&rtr_update_overflow, memory_order_seq_cst)) { | ||
| 90 | - while (read(socket, &rec, sizeof(struct pfx_record)) != -1) | ||
| 91 | - ; | ||
| 92 | + match = bgp_table_subtree_lookup(rrp->bgp->rib[rrp->afi][rrp->safi], | ||
| 93 | + &rrp->prefix); | ||
| 94 | |||
| 95 | - atomic_store_explicit(&rtr_update_overflow, 0, | ||
| 96 | - memory_order_seq_cst); | ||
| 97 | - revalidate_all_routes(); | ||
| 98 | - return 0; | ||
| 99 | - } | ||
| 100 | + node = match; | ||
| 101 | |||
| 102 | - retval = read(socket, &rec, sizeof(struct pfx_record)); | ||
| 103 | - if (retval != sizeof(struct pfx_record)) { | ||
| 104 | - RPKI_DEBUG("Could not read from socket"); | ||
| 105 | - return retval; | ||
| 106 | - } | ||
| 107 | + while (node) { | ||
| 108 | + if (bgp_dest_has_bgp_path_info_data(node)) { | ||
| 109 | + revalidate_bgp_node(node, rrp->afi, rrp->safi); | ||
| 110 | + } | ||
| 111 | |||
| 112 | - /* RTR-Server crashed/terminated, let's handle and switch | ||
| 113 | - * to the second available RTR-Server according to preference. | ||
| 114 | - */ | ||
| 115 | - if (rec.socket && rec.socket->state == RTR_ERROR_FATAL) { | ||
| 116 | - reset(true); | ||
| 117 | - return 0; | ||
| 118 | + node = bgp_route_next_until(node, match); | ||
| 119 | } | ||
| 120 | |||
| 121 | - prefix = pfx_record_to_prefix(&rec); | ||
| 122 | + XFREE(MTYPE_BGP_RPKI_REVALIDATE, rrp); | ||
| 123 | +} | ||
| 124 | |||
| 125 | - afi_t afi = (rec.prefix.ver == LRTR_IPV4) ? AFI_IP : AFI_IP6; | ||
| 126 | +static void revalidate_single_prefix(struct prefix prefix, afi_t afi) | ||
| 127 | +{ | ||
| 128 | + struct bgp *bgp; | ||
| 129 | + struct listnode *node; | ||
| 130 | |||
| 131 | for (ALL_LIST_ELEMENTS_RO(bm->bgp, node, bgp)) { | ||
| 132 | safi_t safi; | ||
| 133 | |||
| 134 | for (safi = SAFI_UNICAST; safi < SAFI_MAX; safi++) { | ||
| 135 | - if (!bgp->rib[afi][safi]) | ||
| 136 | + struct bgp_table *table = bgp->rib[afi][safi]; | ||
| 137 | + struct rpki_revalidate_prefix *rrp; | ||
| 138 | + | ||
| 139 | + if (!table) | ||
| 140 | continue; | ||
| 141 | |||
| 142 | - struct bgp_dest *match; | ||
| 143 | - struct bgp_dest *node; | ||
| 144 | + rrp = XCALLOC(MTYPE_BGP_RPKI_REVALIDATE, sizeof(*rrp)); | ||
| 145 | + rrp->bgp = bgp; | ||
| 146 | + rrp->prefix = prefix; | ||
| 147 | + rrp->afi = afi; | ||
| 148 | + rrp->safi = safi; | ||
| 149 | + thread_add_event(bm->master, rpki_revalidate_prefix, | ||
| 150 | + rrp, 0, &bgp->t_revalidate[afi][safi]); | ||
| 151 | + } | ||
| 152 | + } | ||
| 153 | +} | ||
| 154 | + | ||
| 155 | +static void bgpd_sync_callback(struct thread *thread) | ||
| 156 | +{ | ||
| 157 | + struct prefix prefix; | ||
| 158 | + struct pfx_record rec; | ||
| 159 | + afi_t afi; | ||
| 160 | + int retval; | ||
| 161 | + | ||
| 162 | + if (atomic_load_explicit(&rtr_update_overflow, memory_order_seq_cst)) { | ||
| 163 | + ssize_t size = 0; | ||
| 164 | |||
| 165 | - match = bgp_table_subtree_lookup(bgp->rib[afi][safi], | ||
| 166 | - prefix); | ||
| 167 | - node = match; | ||
| 168 | + retval = read(rpki_sync_socket_bgpd, &rec, | ||
| 169 | + sizeof(struct pfx_record)); | ||
| 170 | + while (retval != -1) { | ||
| 171 | + if (retval != sizeof(struct pfx_record)) | ||
| 172 | + break; | ||
| 173 | |||
| 174 | - while (node) { | ||
| 175 | - if (bgp_dest_has_bgp_path_info_data(node)) { | ||
| 176 | - revalidate_bgp_node(node, afi, safi); | ||
| 177 | - } | ||
| 178 | + size += retval; | ||
| 179 | + pfx_record_to_prefix(&rec, &prefix); | ||
| 180 | + afi = (rec.prefix.ver == LRTR_IPV4) ? AFI_IP : AFI_IP6; | ||
| 181 | + revalidate_single_prefix(prefix, afi); | ||
| 182 | |||
| 183 | - node = bgp_route_next_until(node, match); | ||
| 184 | - } | ||
| 185 | + retval = read(rpki_sync_socket_bgpd, &rec, | ||
| 186 | + sizeof(struct pfx_record)); | ||
| 187 | } | ||
| 188 | + | ||
| 189 | + atomic_store_explicit(&rtr_update_overflow, 0, | ||
| 190 | + memory_order_seq_cst); | ||
| 191 | + return; | ||
| 192 | } | ||
| 193 | |||
| 194 | - prefix_free(&prefix); | ||
| 195 | - return 0; | ||
| 196 | + retval = read(rpki_sync_socket_bgpd, &rec, sizeof(struct pfx_record)); | ||
| 197 | + if (retval != sizeof(struct pfx_record)) { | ||
| 198 | + RPKI_DEBUG("Could not read from rpki_sync_socket_bgpd"); | ||
| 199 | + return; | ||
| 200 | + } | ||
| 201 | + pfx_record_to_prefix(&rec, &prefix); | ||
| 202 | + | ||
| 203 | + afi = (rec.prefix.ver == LRTR_IPV4) ? AFI_IP : AFI_IP6; | ||
| 204 | + | ||
| 205 | + revalidate_single_prefix(prefix, afi); | ||
| 206 | } | ||
| 207 | |||
| 208 | static void revalidate_bgp_node(struct bgp_dest *bgp_dest, afi_t afi, | ||
| 209 | @@ -446,63 +477,12 @@ static void revalidate_bgp_node(struct bgp_dest *bgp_dest, afi_t afi, | ||
| 210 | } | ||
| 211 | } | ||
| 212 | |||
| 213 | -static void revalidate_all_routes(void) | ||
| 214 | -{ | ||
| 215 | - struct bgp *bgp; | ||
| 216 | - struct listnode *node; | ||
| 217 | - afi_t afi; | ||
| 218 | - safi_t safi; | ||
| 219 | - | ||
| 220 | - for (ALL_LIST_ELEMENTS_RO(bm->bgp, node, bgp)) { | ||
| 221 | - struct peer *peer; | ||
| 222 | - struct listnode *peer_listnode; | ||
| 223 | - | ||
| 224 | - for (ALL_LIST_ELEMENTS_RO(bgp->peer, peer_listnode, peer)) { | ||
| 225 | - FOREACH_AFI_SAFI (afi, safi) { | ||
| 226 | - if (!peer->afc_nego[afi][safi]) | ||
| 227 | - continue; | ||
| 228 | - | ||
| 229 | - if (!peer->bgp->rib[afi][safi]) | ||
| 230 | - continue; | ||
| 231 | - | ||
| 232 | - bgp_soft_reconfig_in(peer, afi, safi); | ||
| 233 | - } | ||
| 234 | - } | ||
| 235 | - } | ||
| 236 | -} | ||
| 237 | - | ||
| 238 | -static void rpki_connection_status_cb(const struct rtr_mgr_group *group | ||
| 239 | - __attribute__((unused)), | ||
| 240 | - enum rtr_mgr_status status, | ||
| 241 | - const struct rtr_socket *socket | ||
| 242 | - __attribute__((unused)), | ||
| 243 | - void *data __attribute__((unused))) | ||
| 244 | -{ | ||
| 245 | - struct pfx_record rec = {0}; | ||
| 246 | - int retval; | ||
| 247 | - | ||
| 248 | - if (rtr_is_stopping || | ||
| 249 | - atomic_load_explicit(&rtr_update_overflow, memory_order_seq_cst)) | ||
| 250 | - return; | ||
| 251 | - | ||
| 252 | - if (status == RTR_MGR_ERROR) | ||
| 253 | - rec.socket = socket; | ||
| 254 | - | ||
| 255 | - retval = write(rpki_sync_socket_rtr, &rec, sizeof(rec)); | ||
| 256 | - if (retval == -1 && (errno == EAGAIN || errno == EWOULDBLOCK)) | ||
| 257 | - atomic_store_explicit(&rtr_update_overflow, 1, | ||
| 258 | - memory_order_seq_cst); | ||
| 259 | - | ||
| 260 | - else if (retval != sizeof(rec)) | ||
| 261 | - RPKI_DEBUG("Could not write to rpki_sync_socket_rtr"); | ||
| 262 | -} | ||
| 263 | - | ||
| 264 | static void rpki_update_cb_sync_rtr(struct pfx_table *p __attribute__((unused)), | ||
| 265 | const struct pfx_record rec, | ||
| 266 | const bool added __attribute__((unused))) | ||
| 267 | { | ||
| 268 | - if (rtr_is_stopping | ||
| 269 | - || atomic_load_explicit(&rtr_update_overflow, memory_order_seq_cst)) | ||
| 270 | + if (rtr_is_stopping || | ||
| 271 | + atomic_load_explicit(&rtr_update_overflow, memory_order_seq_cst)) | ||
| 272 | return; | ||
| 273 | |||
| 274 | int retval = | ||
| 275 | diff --git a/bgpd/bgpd.c b/bgpd/bgpd.c | ||
| 276 | index 7e528b2191..bfe96f0f01 100644 | ||
| 277 | --- a/bgpd/bgpd.c | ||
| 278 | +++ b/bgpd/bgpd.c | ||
| 279 | @@ -3579,6 +3579,10 @@ int bgp_delete(struct bgp *bgp) | ||
| 280 | |||
| 281 | hook_call(bgp_inst_delete, bgp); | ||
| 282 | |||
| 283 | + THREAD_OFF(bgp->t_condition_check); | ||
| 284 | + FOREACH_AFI_SAFI (afi, safi) | ||
| 285 | + THREAD_OFF(bgp->t_revalidate[afi][safi]); | ||
| 286 | + | ||
| 287 | THREAD_OFF(bgp->t_startup); | ||
| 288 | THREAD_OFF(bgp->t_maxmed_onstartup); | ||
| 289 | THREAD_OFF(bgp->t_update_delay); | ||
| 290 | diff --git a/bgpd/bgpd.h b/bgpd/bgpd.h | ||
| 291 | index 8b93c450e8..45db4752f4 100644 | ||
| 292 | --- a/bgpd/bgpd.h | ||
| 293 | +++ b/bgpd/bgpd.h | ||
| 294 | @@ -426,6 +426,7 @@ struct bgp { | ||
| 295 | /* BGP update delay on startup */ | ||
| 296 | struct thread *t_update_delay; | ||
| 297 | struct thread *t_establish_wait; | ||
| 298 | + struct thread *t_revalidate[AFI_MAX][SAFI_MAX]; | ||
| 299 | uint8_t update_delay_over; | ||
| 300 | uint8_t main_zebra_update_hold; | ||
| 301 | uint8_t main_peers_update_hold; | ||
| 302 | -- | ||
| 303 | 2.35.5 | ||
| 304 | |||
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 \ | |||
| 34 | file://CVE-2024-31950.patch \ | 34 | file://CVE-2024-31950.patch \ |
| 35 | file://CVE-2024-31951.patch \ | 35 | file://CVE-2024-31951.patch \ |
| 36 | file://CVE-2024-31948.patch \ | 36 | file://CVE-2024-31948.patch \ |
| 37 | file://CVE-2024-55553.patch \ | ||
| 37 | " | 38 | " |
| 38 | 39 | ||
| 39 | SRCREV = "79188bf710e92acf42fb5b9b0a2e9593a5ee9b05" | 40 | SRCREV = "79188bf710e92acf42fb5b9b0a2e9593a5ee9b05" |
