<p>Jenkins2 <strong>merged</strong> this change.</p><p><a href="https://gerrit.asterisk.org/8375">View Change</a></p><div style="white-space:pre-wrap">Approvals:
  Joshua Colp: Looks good to me, but someone else must approve
  George Joseph: Looks good to me, approved
  Jenkins2: Approved for Submit

</div><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;">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: merged </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>
<div style="display:none"> Gerrit-Reviewer: George Joseph <gjoseph@digium.com> </div>
<div style="display:none"> Gerrit-Reviewer: Jenkins2 </div>
<div style="display:none"> Gerrit-Reviewer: Joshua Colp <jcolp@digium.com> </div>