From 0154d8ce45a5099d2d0b9dd3de4e67d4a902d3f5 Mon Sep 17 00:00:00 2001 From: Donald Sharp Date: Wed, 18 Nov 2020 11:04:27 -0500 Subject: [PATCH] bgpd, lib, nhrpd, zebra: verify return of sockunion2hostprefix The return from sockunion2hostprefix tells us if the conversion succeeded or not. There are places in the code where we always assume that it just `works`, since it can fail notice and try to do the right thing. Please note that failure of this function for most cases of sockunion2hostprefix is highly highly unlikely as that the sockunion was already created and tested elsewhere it's just that this function can fail. Signed-off-by: Donald Sharp --- bgpd/bgp_bmp.c | 5 ++++- bgpd/bgp_network.c | 4 +++- bgpd/bgp_route.c | 4 +++- bgpd/bgp_vty.c | 12 ++++++------ bgpd/bgpd.c | 7 ++++--- lib/vty.c | 6 +++++- nhrpd/nhrp_cache.c | 5 +++-- nhrpd/nhrp_shortcut.c | 4 +++- zebra/zebra_vty.c | 3 +++ 9 files changed, 34 insertions(+), 16 deletions(-) diff --git a/bgpd/bgp_bmp.c b/bgpd/bgp_bmp.c index af88547ca9..f115f18f07 100644 --- a/bgpd/bgp_bmp.c +++ b/bgpd/bgp_bmp.c @@ -1351,7 +1351,10 @@ static struct bmp *bmp_open(struct bmp_targets *bt, int bmp_sock) set_cloexec(bmp_sock); shutdown(bmp_sock, SHUT_RD); - sockunion2hostprefix(&su, &p); + if (!sockunion2hostprefix(&su, &p)) { + close(bmp_sock); + return NULL; + } acl = NULL; switch (p.family) { diff --git a/bgpd/bgp_network.c b/bgpd/bgp_network.c index cae11ae7bd..fcbdb2969f 100644 --- a/bgpd/bgp_network.c +++ b/bgpd/bgp_network.c @@ -639,7 +639,9 @@ static int bgp_update_address(struct interface *ifp, const union sockunion *dst, struct listnode *node; int common; - sockunion2hostprefix(dst, &d); + if (!sockunion2hostprefix(dst, &d)) + return 1; + sel = NULL; common = -1; diff --git a/bgpd/bgp_route.c b/bgpd/bgp_route.c index 87e8feb3bf..df30897dc6 100644 --- a/bgpd/bgp_route.c +++ b/bgpd/bgp_route.c @@ -13699,7 +13699,9 @@ uint8_t bgp_distance_apply(const struct prefix *p, struct bgp_path_info *pinfo, return pinfo->attr->distance; /* Check source address. */ - sockunion2hostprefix(&peer->su, &q); + if (!sockunion2hostprefix(&peer->su, &q)) + return 0; + dest = bgp_node_match(bgp_distance_table[afi][safi], &q); if (dest) { bdistance = bgp_dest_get_bgp_distance_info(dest); diff --git a/bgpd/bgp_vty.c b/bgpd/bgp_vty.c index 40e9707866..72d250d2bb 100644 --- a/bgpd/bgp_vty.c +++ b/bgpd/bgp_vty.c @@ -12448,9 +12448,9 @@ static void bgp_show_peer(struct vty *vty, struct peer *p, bool use_json, if (dn_flag[0]) { struct prefix prefix, *range = NULL; - sockunion2hostprefix(&(p->su), &prefix); - range = peer_group_lookup_dynamic_neighbor_range( - p->group, &prefix); + if (sockunion2hostprefix(&(p->su), &prefix)) + range = peer_group_lookup_dynamic_neighbor_range( + p->group, &prefix); if (range) { prefix2str(range, buf1, sizeof(buf1)); @@ -12467,9 +12467,9 @@ static void bgp_show_peer(struct vty *vty, struct peer *p, bool use_json, if (dn_flag[0]) { struct prefix prefix, *range = NULL; - sockunion2hostprefix(&(p->su), &prefix); - range = peer_group_lookup_dynamic_neighbor_range( - p->group, &prefix); + if (sockunion2hostprefix(&(p->su), &prefix)) + range = peer_group_lookup_dynamic_neighbor_range( + p->group, &prefix); if (range) { vty_out(vty, diff --git a/bgpd/bgpd.c b/bgpd/bgpd.c index fd2c431eac..25f3526a23 100644 --- a/bgpd/bgpd.c +++ b/bgpd/bgpd.c @@ -2802,8 +2802,8 @@ int peer_group_listen_range_del(struct peer_group *group, struct prefix *range) if (!peer_dynamic_neighbor(peer)) continue; - sockunion2hostprefix(&peer->su, &prefix2); - if (prefix_match(prefix, &prefix2)) { + if (sockunion2hostprefix(&peer->su, &prefix2) + && prefix_match(prefix, &prefix2)) { if (bgp_debug_neighbor_events(peer)) zlog_debug( "Deleting dynamic neighbor %s group %s upon delete of listen range %pFX", @@ -3834,7 +3834,8 @@ struct peer *peer_lookup_dynamic_neighbor(struct bgp *bgp, union sockunion *su) int dncount; char buf[PREFIX2STR_BUFFER]; - sockunion2hostprefix(su, &prefix); + if (!sockunion2hostprefix(su, &prefix)) + return NULL; /* See if incoming connection matches a configured listen range. */ group = peer_group_lookup_dynamic_neighbor(bgp, &prefix, &listen_range); diff --git a/lib/vty.c b/lib/vty.c index fea4c49032..1eb4171630 100644 --- a/lib/vty.c +++ b/lib/vty.c @@ -1810,7 +1810,11 @@ static int vty_accept(struct thread *thread) set_nonblocking(vty_sock); set_cloexec(vty_sock); - sockunion2hostprefix(&su, &p); + if (!sockunion2hostprefix(&su, &p)) { + zlog_info("Vty unable to convert prefix from sockunion %s", + sockunion2str(&su, buf, SU_ADDRSTRLEN)); + return -1; + } /* VTY's accesslist apply. */ if (p.family == AF_INET && vty_accesslist_name) { diff --git a/nhrpd/nhrp_cache.c b/nhrpd/nhrp_cache.c index 42f6a88f95..f7c71c2218 100644 --- a/nhrpd/nhrp_cache.c +++ b/nhrpd/nhrp_cache.c @@ -122,7 +122,8 @@ static void nhrp_cache_update_route(struct nhrp_cache *c) char buf[3][SU_ADDRSTRLEN]; struct nhrp_interface *nifp; - sockunion2hostprefix(&c->remote_addr, &pfx); + if (!sockunion2hostprefix(&c->remote_addr, &pfx)) + return; if (p && nhrp_peer_check(p, 1)) { if (sockunion_family(&c->cur.remote_nbma_natoa) != AF_UNSPEC) { @@ -186,7 +187,7 @@ static void nhrp_cache_update_route(struct nhrp_cache *c) c->nhrp_route_installed = 0; } if (c->route_installed) { - sockunion2hostprefix(&c->remote_addr, &pfx); + assert(sockunion2hostprefix(&c->remote_addr, &pfx)); notifier_call(&c->notifier_list, NOTIFY_CACHE_DOWN); nhrp_route_announce(0, c->cur.type, &pfx, NULL, NULL, 0); diff --git a/nhrpd/nhrp_shortcut.c b/nhrpd/nhrp_shortcut.c index 9a6f77334f..2359cfa4ac 100644 --- a/nhrpd/nhrp_shortcut.c +++ b/nhrpd/nhrp_shortcut.c @@ -397,7 +397,9 @@ void nhrp_shortcut_initiate(union sockunion *addr) struct prefix p; struct nhrp_shortcut *s; - sockunion2hostprefix(addr, &p); + if (!sockunion2hostprefix(addr, &p)) + return; + s = nhrp_shortcut_get(&p); if (s && s->type != NHRP_CACHE_INCOMPLETE) { s->addr = *addr; diff --git a/zebra/zebra_vty.c b/zebra/zebra_vty.c index ea7baa2565..8f73825700 100644 --- a/zebra/zebra_vty.c +++ b/zebra/zebra_vty.c @@ -1277,6 +1277,9 @@ DEFPY (show_ip_nht, if (addr) p = sockunion2hostprefix(addr, &prefix); + if (!p) + return CMD_WARNING; + zebra_print_rnh_table(vrf_id, afi, vty, rtype, p); return CMD_SUCCESS; }