[bgpd] struct peer must have bgp field valid (redistribute crash)
2006-10-19 Paul Jakma <paul.jakma@sun.com>
* 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.
diff --git a/bgpd/ChangeLog b/bgpd/ChangeLog
index 83f9d49..701627c 100644
--- a/bgpd/ChangeLog
+++ b/bgpd/ChangeLog
@@ -1,3 +1,13 @@
+2006-10-19 Paul Jakma <paul.jakma@sun.com>
+
+ * 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 <paul.jakma@sun.com>
* 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 7b36974..3584b21 100644
--- a/bgpd/bgp_route.c
+++ b/bgpd/bgp_route.c
@@ -196,6 +196,9 @@
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 1ead13c..3f84107 100644
--- a/bgpd/bgpd.c
+++ b/bgpd/bgpd.c
@@ -765,13 +765,18 @@
/* 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->status = Idle;
peer->ostatus = Idle;
peer->weight = 0;
+ peer->bgp = bgp;
peer = peer_lock (peer); /* initial reference */
/* Set default flags. */
@@ -821,8 +827,7 @@
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 @@
{
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 @@
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 @@
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 ();