Skip to content
Permalink
Browse files

lib/bgpd: re-fix bgp_info_extra_free()

Make the wart slightly less bad... also there is still a possible write
after free here.  This needs to be fixed again, properly, by some
structure changes.

Signed-off-by: David Lamparter <equinox@diac24.net>
  • Loading branch information...
eqvinox committed Aug 18, 2018
1 parent a2dc705 commit 0e70e6c89d69976cde1b79bba6ac23d233b19566
Showing with 22 additions and 10 deletions.
  1. +18 −2 bgpd/bgp_route.c
  2. +2 −2 bgpd/bgp_table.h
  3. +2 −6 lib/table.h
@@ -188,8 +188,24 @@ static void bgp_info_extra_free(struct bgp_info_extra **extra)
if (e->parent) {
struct bgp_info *bi = (struct bgp_info *)e->parent;

if (bi->net)
bi->net = bgp_unlock_node((struct bgp_node *)bi->net);
if (bi->net) {
/* FIXME: since multiple e may have the same e->parent
* and e->parent->net is holding a refcount for each
* of them, we need to do some fudging here.
*
* WARNING: if bi->net->lock drops to 0, bi may be
* freed as well (because bi->net was holding the
* last reference to bi) => write after free!
*/
unsigned refcount;

bi = bgp_info_lock(bi);
refcount = bi->net->lock - 1;
bgp_unlock_node((struct bgp_node *)bi->net);
if (!refcount)
bi->net = NULL;
bgp_info_unlock(bi);
}
bgp_info_unlock(e->parent);
e->parent = NULL;
}
@@ -128,9 +128,9 @@ static inline struct bgp_node *bgp_node_parent_nolock(struct bgp_node *node)
/*
* bgp_unlock_node
*/
static inline struct bgp_node *bgp_unlock_node(struct bgp_node *node)
static inline void bgp_unlock_node(struct bgp_node *node)
{
return (struct bgp_node *)route_unlock_node(bgp_node_to_rnode(node));
route_unlock_node(bgp_node_to_rnode(node));
}

/*
@@ -235,17 +235,13 @@ static inline struct route_node *route_lock_node(struct route_node *node)
}

/* Unlock node. */
static inline struct route_node *route_unlock_node(struct route_node *node)
static inline void route_unlock_node(struct route_node *node)
{
assert(node->lock > 0);
(*(unsigned *)&node->lock)--;

if (node->lock == 0) {
if (node->lock == 0)
route_node_delete(node);
return NULL;
}

return node;
}

/*

0 comments on commit 0e70e6c

Please sign in to comment.
You can’t perform that action at this time.