From: Donald Sharp Date: Mon, 2 Dec 2019 14:37:47 +0000 (-0500) Subject: bgpd: Prevent crash in bgp_table_range_lookup X-Git-Tag: base_7.3~123^2 X-Git-Url: https://git.puffer.fish/?a=commitdiff_plain;h=5911f65c7bcb05ee81a744bdc8eec5bdae54a591;p=matthieu%2Ffrr.git bgpd: Prevent crash in bgp_table_range_lookup The function bgp_table_range_lookup attempts to walk down the table node data structures to find a list of matching nodes. We need to guard against the current node from not matching and not having anything in the child nodes. Add a bit of code to guard against this. Traceback that lead me down this path: Nov 24 12:22:38 frr bgpd[20257]: Received signal 11 at 1574616158 (si_addr 0x2, PC 0x46cdc3); aborting... Nov 24 12:22:38 frr bgpd[20257]: Backtrace for 11 stack frames: Nov 24 12:22:38 frr bgpd[20257]: /lib64/libfrr.so.0(zlog_backtrace_sigsafe+0x67) [0x7fd1ad445957] Nov 24 12:22:38 frr bgpd[20257]: /lib64/libfrr.so.0(zlog_signal+0x113) [0x7fd1ad445db3]1ad445957] Nov 24 12:22:38 frr bgpd[20257]: /lib64/libfrr.so.0(+0x70e65) [0x7fd1ad465e65]ad445db3]1ad445957] Nov 24 12:22:38 frr bgpd[20257]: /lib64/libpthread.so.0(+0xf5f0) [0x7fd1abd605f0]45db3]1ad445957] Nov 24 12:22:38 frr bgpd[20257]: /usr/lib/frr/bgpd(bgp_table_range_lookup+0x63) [0x46cdc3]445957] Nov 24 12:22:38 frr bgpd[20257]: /usr/lib64/frr/modules/bgpd_rpki.so(+0x4f0d) [0x7fd1a934ff0d]57] Nov 24 12:22:38 frr bgpd[20257]: /lib64/libfrr.so.0(thread_call+0x60) [0x7fd1ad4736e0]934ff0d]57] Nov 24 12:22:38 frr bgpd[20257]: /lib64/libfrr.so.0(frr_run+0x128) [0x7fd1ad443ab8]e0]934ff0d]57] Nov 24 12:22:38 frr bgpd[20257]: /usr/lib/frr/bgpd(main+0x2e3) [0x41c043]1ad443ab8]e0]934ff0d]57] Nov 24 12:22:38 frr bgpd[20257]: /lib64/libc.so.6(__libc_start_main+0xf5) [0x7fd1ab9a5505]f0d]57] Nov 24 12:22:38 frr bgpd[20257]: /usr/lib/frr/bgpd() [0x41d9bb]main+0xf5) [0x7fd1ab9a5505]f0d]57] Nov 24 12:22:38 frr bgpd[20257]: in thread bgpd_sync_callback scheduled from bgpd/bgp_rpki.c:351#012; aborting... Nov 24 12:22:38 frr watchfrr[6779]: [EC 268435457] bgpd state -> down : read returned EOF Nov 24 12:22:38 frr zebra[5952]: [EC 4043309116] Client 'bgp' encountered an error and is shutting down. Nov 24 12:22:38 frr zebra[5952]: zebra/zebra_ptm.c:1345 failed to find process pid registration Nov 24 12:22:38 frr zebra[5952]: client 15 disconnected. 0 bgp routes removed from the rib I am not really 100% sure what we are really trying to do with this function, but we must guard against child nodes not having any data. Fixes: #5440 Signed-off-by: Donald Sharp --- diff --git a/bgpd/bgp_table.c b/bgpd/bgp_table.c index 53175bfccf..b75246b172 100644 --- a/bgpd/bgp_table.c +++ b/bgpd/bgp_table.c @@ -159,7 +159,8 @@ void bgp_table_range_lookup(const struct bgp_table *table, struct prefix *p, if (node == NULL) return; - while (node->p.prefixlen <= p->prefixlen && prefix_match(&node->p, p)) { + while (node && + node->p.prefixlen <= p->prefixlen && prefix_match(&node->p, p)) { if (bgp_node_has_bgp_path_info_data(node) && node->p.prefixlen == p->prefixlen) { matched = node; @@ -169,14 +170,20 @@ void bgp_table_range_lookup(const struct bgp_table *table, struct prefix *p, &p->u.prefix, node->p.prefixlen)]); } + if (!node) + return; + if (matched == NULL && node->p.prefixlen <= maxlen && prefix_match(p, &node->p) && node->parent == NULL) matched = node; else if ((matched == NULL && node->p.prefixlen > maxlen) || !node->parent) return; - else if (matched == NULL) + else if (matched == NULL && node->parent) matched = node = bgp_node_from_rnode(node->parent); + if (!matched) + return; + if (bgp_node_has_bgp_path_info_data(matched)) { bgp_lock_node(matched); listnode_add(matches, matched);