Skip to content
Permalink
Browse files

pimd: Fix pim_mroute_del crash while terminating pimd

When pimd is getting terminated, pim_upstream_del() gets called as
part of cleaning process. pim_upstream_del() deletes the route and
assigns NULL to the up->channel_oil. It also deletes each if_channel
by calling the function pim_ifchannel_delete().
pim_ifchannel_delete() internally calls the caller function pim_upstream_del(),
if it is the last ifchannel for that upstream. So pim_upstream_del
is getting called twice, which will access the up->channel_oil which
was already set to NULL before. This results in crash.

Fix:
pim_ifchannel_delete() should call pim_upstream_del (caller function)
only if the up->ref_count > 0. Added an assert(up->ref_count > 0) in
the function pim_upstream_del().

Signed-off-by: Sarita Patra <saritap@vmware.com>
  • Loading branch information...
root
root committed Aug 22, 2018
1 parent f8a5233 commit e83f3b316a3a582f31031c9eba0273259a155711
Showing with 12 additions and 1 deletion.
  1. +10 −1 pimd/pim_ifchannel.c
  2. +2 −0 pimd/pim_upstream.c
@@ -174,7 +174,16 @@ void pim_ifchannel_delete(struct pim_ifchannel *ch)
ifchannel list is empty before deleting upstream_del
ref count will take care of it.
*/
pim_upstream_del(pim_ifp->pim, ch->upstream, __PRETTY_FUNCTION__);
if (ch->upstream->ref_count > 0)
pim_upstream_del(pim_ifp->pim, ch->upstream,
__PRETTY_FUNCTION__);

else
zlog_warn("%s: Avoiding deletion of upstream with ref_count %d "
"from ifchannel(%s): %s", __PRETTY_FUNCTION__,
ch->upstream->ref_count, ch->interface->name,
ch->sg_str);

ch->upstream = NULL;

THREAD_OFF(ch->t_ifjoin_expiry_timer);
@@ -167,6 +167,8 @@ struct pim_upstream *pim_upstream_del(struct pim_instance *pim,
up->ref_count, up->flags,
up->channel_oil->oil_ref_count);

assert(up->ref_count > 0);

--up->ref_count;

if (up->ref_count >= 1)

0 comments on commit e83f3b3

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