summaryrefslogtreecommitdiff
path: root/bgpd
diff options
context:
space:
mode:
authorPaul Jakma <paul.jakma@sun.com>2006-10-22 19:13:07 +0000
committerPaul Jakma <paul.jakma@sun.com>2006-10-22 19:13:07 +0000
commit6f58544db526b4dfb09d45f8507926b0ae5fe12b (patch)
treef73d22b4ff92eaef337a6d9af8a1923d730e9a21 /bgpd
parented3ebfa36b45fe487015e1918e848f0ff4500bff (diff)
[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.
Diffstat (limited to 'bgpd')
-rw-r--r--bgpd/ChangeLog10
-rw-r--r--bgpd/bgp_route.c3
-rw-r--r--bgpd/bgpd.c21
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 <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 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 ();