<p>Richard Mudgett has uploaded this change for <strong>review</strong>.</p><p><a href="https://gerrit.asterisk.org/8375">View Change</a></p><pre style="font-family: monospace,monospace; white-space: pre-wrap;">res_pjsip_refer.c: Fix attended transfer race condition crash.<br><br>The transferrer's session channel was destroyed by the transferrer's<br>serializer thread in a race condition with the transfer target's<br>serializer thread during an attended transfer. The transfer target's<br>serializer was attempting to clean up a deferred end status on behalf of<br>the transferrer's channel when it should have passed the action to the<br>transferrer's serializer. When the transfer target's serializer lost the<br>race then both threads wind up trying to end the transferrer's session.<br><br>* Push the ast_sip_session_end_if_deferred() call onto the transferrer's<br>serializer to avoid a race condition that results in a crash. The<br>session_end() function that could be called by<br>ast_sip_session_end_if_deferred() really must be executed by the<br>transferrer's serializer to avoid this kind of crash.<br><br>ASTERISK-27568<br><br>Change-Id: Iacda724e7cb24d7520e49b2fd7e504aa398d7238<br>---<br>M res/res_pjsip_refer.c<br>1 file changed, 24 insertions(+), 8 deletions(-)<br><br></pre><pre style="font-family: monospace,monospace; white-space: pre-wrap;">git pull ssh://gerrit.asterisk.org:29418/asterisk refs/changes/75/8375/1</pre><pre style="font-family: monospace,monospace; white-space: pre-wrap;">diff --git a/res/res_pjsip_refer.c b/res/res_pjsip_refer.c<br>index 8e179fc..964c231 100644<br>--- a/res/res_pjsip_refer.c<br>+++ b/res/res_pjsip_refer.c<br>@@ -468,10 +468,20 @@<br> return attended;<br> }<br> <br>-static int defer_termination_cancel(void *data)<br>+static int session_end_if_deferred_task(void *data)<br> {<br> struct ast_sip_session *session = data;<br> <br>+ ast_sip_session_end_if_deferred(session);<br>+ ao2_ref(session, -1);<br>+ return 0;<br>+}<br>+<br>+static int defer_termination_cancel_task(void *data)<br>+{<br>+ struct ast_sip_session *session = data;<br>+<br>+ ast_sip_session_end_if_deferred(session);<br> ast_sip_session_defer_termination_cancel(session);<br> ao2_ref(session, -1);<br> return 0;<br>@@ -513,6 +523,7 @@<br> {<br> struct refer_attended *attended = data;<br> int response;<br>+ int (*task_cb)(void *data);<br> <br> if (attended->transferer_second->channel) {<br> ast_debug(3, "Performing a REFER attended transfer - Transferer #1: %s Transferer #2: %s\n",<br>@@ -543,13 +554,18 @@<br> }<br> }<br> <br>- ast_sip_session_end_if_deferred(attended->transferer);<br>- if (response != 200) {<br>- if (!ast_sip_push_task(attended->transferer->serializer,<br>- defer_termination_cancel, attended->transferer)) {<br>- /* Gave the ref to the pushed task. */<br>- attended->transferer = NULL;<br>- }<br>+ if (response == 200) {<br>+ task_cb = session_end_if_deferred_task;<br>+ } else {<br>+ task_cb = defer_termination_cancel_task;<br>+ }<br>+ if (!ast_sip_push_task(attended->transferer->serializer,<br>+ task_cb, attended->transferer)) {<br>+ /* Gave the ref to the pushed task. */<br>+ attended->transferer = NULL;<br>+ } else {<br>+ /* Do this anyway even though it is the wrong serializer. */<br>+ ast_sip_session_end_if_deferred(attended->transferer);<br> }<br> <br> ao2_ref(attended, -1);<br></pre><p>To view, visit <a href="https://gerrit.asterisk.org/8375">change 8375</a>. To unsubscribe, visit <a href="https://gerrit.asterisk.org/settings">settings</a>.</p><div itemscope itemtype="http://schema.org/EmailMessage"><div itemscope itemprop="action" itemtype="http://schema.org/ViewAction"><link itemprop="url" href="https://gerrit.asterisk.org/8375"/><meta itemprop="name" content="View Change"/></div></div>
<div style="display:none"> Gerrit-Project: asterisk </div>
<div style="display:none"> Gerrit-Branch: 13 </div>
<div style="display:none"> Gerrit-MessageType: newchange </div>
<div style="display:none"> Gerrit-Change-Id: Iacda724e7cb24d7520e49b2fd7e504aa398d7238 </div>
<div style="display:none"> Gerrit-Change-Number: 8375 </div>
<div style="display:none"> Gerrit-PatchSet: 1 </div>
<div style="display:none"> Gerrit-Owner: Richard Mudgett <rmudgett@digium.com> </div>