From 6f58544db526b4dfb09d45f8507926b0ae5fe12b Mon Sep 17 00:00:00 2001 From: Paul Jakma Date: Sun, 22 Oct 2006 19:13:07 +0000 Subject: [bgpd] struct peer must have bgp field valid (redistribute crash) 2006-10-19 Paul Jakma * bgpd.c: (peer_new) bgp element of peer absolutely must be filled in, make peer_new() require it as argument and update all callers. Fixes a crash reported by Jan 'yanek' Bortl and Andrew Schorr where bgpd would crash in bgp_pcount_adjust trying to dereference the bgp member of bgp->peer_self, triggered through redistribution. * bgp_route.c: (bgp_pcount_adjust) assert sanity of arguments. --- bgpd/ChangeLog | 10 ++++++++++ bgpd/bgp_route.c | 3 +++ bgpd/bgpd.c | 21 ++++++++++++--------- 3 files changed, 25 insertions(+), 9 deletions(-) diff --git a/bgpd/ChangeLog b/bgpd/ChangeLog index 83f9d493..701627c8 100644 --- a/bgpd/ChangeLog +++ b/bgpd/ChangeLog @@ -1,3 +1,13 @@ +2006-10-19 Paul Jakma + + * bgpd.c: (peer_new) bgp element of peer absolutely must be + filled in, make peer_new() require it as argument and update + all callers. Fixes a crash reported by Jan 'yanek' Bortl and + Andrew Schorr where bgpd would crash in bgp_pcount_adjust + trying to dereference the bgp member of bgp->peer_self, + triggered through redistribution. + * bgp_route.c: (bgp_pcount_adjust) assert sanity of arguments. + 2006-10-15 Paul Jakma * bgp_route.c: (bgp_table_stats_walker) NULL deref if table is diff --git a/bgpd/bgp_route.c b/bgpd/bgp_route.c index 7b369748..3584b21a 100644 --- a/bgpd/bgp_route.c +++ b/bgpd/bgp_route.c @@ -196,6 +196,9 @@ bgp_info_delete (struct bgp_node *rn, struct bgp_info *ri) static void bgp_pcount_adjust (struct bgp_node *rn, struct bgp_info *ri) { + assert (rn && rn->table); + assert (ri && ri->peer && ri->peer->bgp); + /* Ignore 'pcount' for RS-client tables */ if (rn->table->type != BGP_TABLE_MAIN || ri->peer == ri->peer->bgp->peer_self) diff --git a/bgpd/bgpd.c b/bgpd/bgpd.c index 1ead13cf..3f841078 100644 --- a/bgpd/bgpd.c +++ b/bgpd/bgpd.c @@ -765,13 +765,18 @@ peer_unlock (struct peer *peer) /* Allocate new peer object, implicitely locked. */ static struct peer * -peer_new () +peer_new (struct bgp *bgp) { afi_t afi; safi_t safi; struct peer *peer; struct servent *sp; - + + /* bgp argument is absolutely required */ + assert (bgp); + if (!bgp) + return NULL; + /* Allocate new peer. */ peer = XCALLOC (MTYPE_BGP_PEER, sizeof (struct peer)); @@ -783,6 +788,7 @@ peer_new () peer->status = Idle; peer->ostatus = Idle; peer->weight = 0; + peer->bgp = bgp; peer = peer_lock (peer); /* initial reference */ /* Set default flags. */ @@ -821,8 +827,7 @@ peer_create (union sockunion *su, struct bgp *bgp, as_t local_as, struct peer *peer; char buf[SU_ADDRSTRLEN]; - peer = peer_new (); - peer->bgp = bgp; + peer = peer_new (bgp); peer->su = *su; peer->local_as = local_as; peer->as = remote_as; @@ -868,8 +873,7 @@ peer_create_accept (struct bgp *bgp) { struct peer *peer; - peer = peer_new (); - peer->bgp = bgp; + peer = peer_new (bgp); peer = peer_lock (peer); /* bgp peer list reference */ listnode_add_sort (bgp->peer, peer); @@ -1344,11 +1348,10 @@ peer_group_get (struct bgp *bgp, const char *name) group->bgp = bgp; group->name = strdup (name); group->peer = list_new (); - group->conf = peer_new (); + group->conf = peer_new (bgp); if (! bgp_flag_check (bgp, BGP_FLAG_NO_DEFAULT_IPV4)) group->conf->afc[AFI_IP][SAFI_UNICAST] = 1; group->conf->host = strdup (name); - group->conf->bgp = bgp; group->conf->group = group; group->conf->as = 0; group->conf->ttl = 1; @@ -1883,7 +1886,7 @@ bgp_create (as_t *as, const char *name) if ( (bgp = XCALLOC (MTYPE_BGP, sizeof (struct bgp))) == NULL) return NULL; - bgp->peer_self = peer_new (); + bgp->peer_self = peer_new (bgp); bgp->peer_self->host = strdup ("Static announcement"); bgp->peer = list_new (); -- cgit v1.2.1