bgpd: fix invalid memory access in peer_free()

We shoult not call bgp_unlock() before calling
bgp_delete_connected_nexthop() in the peer_free() function. Otherwise,
if bgp->lock reaches zero, bgp_free() is called and peer->bgp becomes
an invalid pointer in the bgp_delete_connected_nexthop() function.

To fix this, move the call to bgp_unlock() to the end of peer_free().

Bug exposed by commit 37d361e ("bgpd: plug several memleaks").

Signed-off-by: Renato Westphal <renato@opensourcerouting.org>
Signed-off-by: David Lamparter <equinox@opensourcerouting.org>
This commit is contained in:
Renato Westphal 2016-11-28 16:47:13 -02:00 committed by David Lamparter
parent 34620e24b5
commit ff999357fd

View File

@ -1018,8 +1018,6 @@ peer_free (struct peer *peer)
{
assert (peer->status == Deleted);
bgp_unlock(peer->bgp);
/* this /ought/ to have been done already through bgp_stop earlier,
* but just to be sure..
*/
@ -1085,6 +1083,8 @@ peer_free (struct peer *peer)
bfd_info_free(&(peer->bfd_info));
bgp_unlock(peer->bgp);
memset (peer, 0, sizeof (struct peer));
XFREE (MTYPE_BGP_PEER, peer);