From b7e40944a26b80be83d44cdac1bed73c71ccc0d8 Mon Sep 17 00:00:00 2001 From: Donald Sharp Date: Thu, 5 Mar 2020 09:26:11 -0500 Subject: [PATCH] pimd: Prevent use after free from pim_mlag_up_peer_deref There exists a chain of events where calling pim_mlag_up_peer_deref can free the up pointer. Prevent a use after free by returning the up pointer as needed and checking to make sure we are ok. Signed-off-by: Donald Sharp --- pimd/pim_mlag.c | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) diff --git a/pimd/pim_mlag.c b/pimd/pim_mlag.c index cbde45abb8..f476cb5981 100644 --- a/pimd/pim_mlag.c +++ b/pimd/pim_mlag.c @@ -210,17 +210,20 @@ static void pim_mlag_up_peer_add(struct mlag_mroute_add *msg) * - if a local entry continues to exisy and has a MLAG OIF DF election * is re-run (at the end of which the local entry will be the DF). */ -static void pim_mlag_up_peer_deref(struct pim_instance *pim, - struct pim_upstream *up) +static struct pim_upstream *pim_mlag_up_peer_deref(struct pim_instance *pim, + struct pim_upstream *up) { if (!PIM_UPSTREAM_FLAG_TEST_MLAG_PEER(up->flags)) - return; + return up; PIM_UPSTREAM_FLAG_UNSET_MLAG_PEER(up->flags); up = pim_upstream_del(pim, up, __func__); if (up) pim_mlag_up_df_role_elect(pim, up); + + return up; } + static void pim_mlag_up_peer_del(struct mlag_mroute_del *msg) { struct pim_upstream *up; @@ -256,7 +259,7 @@ static void pim_mlag_up_peer_del(struct mlag_mroute_del *msg) return; } - pim_mlag_up_peer_deref(pim, up); + (void)pim_mlag_up_peer_deref(pim, up); } /* When we lose connection to the local MLAG daemon we can drop all peer @@ -300,12 +303,13 @@ static void pim_mlag_up_peer_del_all(void) up = listnode_head(temp); listnode_delete(temp, up); - pim_mlag_up_peer_deref(pim, up); + up = pim_mlag_up_peer_deref(pim, up); /* * This is the deletion of the reference added * above */ - pim_upstream_del(pim, up, __func__); + if (up) + pim_upstream_del(pim, up, __func__); } }