From: David Vossel Date: Mon, 29 Jun 2009 17:04:04 +0000 (+0000) Subject: segfault after SPINLOCK schedule delete X-Git-Tag: 1.4.26~30 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=4f3580b88272b5a11162372bfb8493484b3f456a;p=thirdparty%2Fasterisk.git segfault after SPINLOCK schedule delete Using the SPINLOCK schedule delete macro can result in the iax_pvt lock being given up. This makes it possible for the iax_pvt to dissappear when we thought we held the mutex the entire time. To resolve this, the iax_pvt's ref count is incremented. (closes issue #15377) Reported by: aragon Patches: iax_spin_issue_1.4.diff uploaded by dvossel (license 671) Tested by: aragon, dvossel git-svn-id: https://origsvn.digium.com/svn/asterisk/branches/1.4@204067 65c4cc65-6c06-0410-ace0-fbb531ad65f3 --- diff --git a/channels/chan_iax2.c b/channels/chan_iax2.c index a75d9b6d56..fa17824539 100644 --- a/channels/chan_iax2.c +++ b/channels/chan_iax2.c @@ -1358,10 +1358,20 @@ retry: goto retry; } } - if (!owner && iaxs[callno]) { - AST_SCHED_DEL_SPINLOCK(sched, iaxs[callno]->lagid, &iaxsl[callno]); - AST_SCHED_DEL_SPINLOCK(sched, iaxs[callno]->pingid, &iaxsl[callno]); - iaxs[callno] = NULL; + + /* SPINLOCK gives up the pvt lock so the scheduler and iax2_pvt don't deadlock. Since we + * give up the pvt lock, the pvt could be destroyed from underneath us. To guarantee + * the pvt stays around, a ref count is added to it. */ + if (!owner && pvt) { + ao2_ref(pvt, +1); + AST_SCHED_DEL_SPINLOCK(sched, pvt->lagid, &iaxsl[pvt->callno]); + AST_SCHED_DEL_SPINLOCK(sched, pvt->pingid, &iaxsl[pvt->callno]); + ao2_ref(pvt, -1); + if (iaxs[callno]) { + iaxs[callno] = NULL; + } else { + pvt = NULL; + } } if (pvt) {