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
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) {