mirror of
https://git.proxmox.com/git/mirror_frr
synced 2025-08-13 22:57:45 +00:00
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 <sharpd@cumulusnetworks.com>
This commit is contained in:
parent
3c685e64ff
commit
b7e40944a2
@ -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
|
* - 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).
|
* 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,
|
static struct pim_upstream *pim_mlag_up_peer_deref(struct pim_instance *pim,
|
||||||
struct pim_upstream *up)
|
struct pim_upstream *up)
|
||||||
{
|
{
|
||||||
if (!PIM_UPSTREAM_FLAG_TEST_MLAG_PEER(up->flags))
|
if (!PIM_UPSTREAM_FLAG_TEST_MLAG_PEER(up->flags))
|
||||||
return;
|
return up;
|
||||||
|
|
||||||
PIM_UPSTREAM_FLAG_UNSET_MLAG_PEER(up->flags);
|
PIM_UPSTREAM_FLAG_UNSET_MLAG_PEER(up->flags);
|
||||||
up = pim_upstream_del(pim, up, __func__);
|
up = pim_upstream_del(pim, up, __func__);
|
||||||
if (up)
|
if (up)
|
||||||
pim_mlag_up_df_role_elect(pim, up);
|
pim_mlag_up_df_role_elect(pim, up);
|
||||||
|
|
||||||
|
return up;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void pim_mlag_up_peer_del(struct mlag_mroute_del *msg)
|
static void pim_mlag_up_peer_del(struct mlag_mroute_del *msg)
|
||||||
{
|
{
|
||||||
struct pim_upstream *up;
|
struct pim_upstream *up;
|
||||||
@ -256,7 +259,7 @@ static void pim_mlag_up_peer_del(struct mlag_mroute_del *msg)
|
|||||||
return;
|
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
|
/* 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);
|
up = listnode_head(temp);
|
||||||
listnode_delete(temp, up);
|
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
|
* This is the deletion of the reference added
|
||||||
* above
|
* above
|
||||||
*/
|
*/
|
||||||
pim_upstream_del(pim, up, __func__);
|
if (up)
|
||||||
|
pim_upstream_del(pim, up, __func__);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user