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

</div><pre style="font-family: monospace,monospace; white-space: pre-wrap;">thirdparty/pjproject: fix deadlock in response retransmissions<br><br>The tdata containing the response can be shared by both the dialog<br>object and the tsx object.  In order to prevent the race condition<br>between the tsx retransmission and the dialog sending a response,<br>clone the tdata before modifying it for the dialog send response.<br><br>ASTERISK-27966 #close<br><br>Change-Id: Ic381004a3a212fe1d8eca0e707fe09dba4a6ab4e<br>---<br>A third-party/pjproject/patches/0110_fix_tdata_rexmit_deadlock.patch<br>1 file changed, 203 insertions(+), 0 deletions(-)<br><br></pre><pre style="font-family: monospace,monospace; white-space: pre-wrap;"><span>diff --git a/third-party/pjproject/patches/0110_fix_tdata_rexmit_deadlock.patch b/third-party/pjproject/patches/0110_fix_tdata_rexmit_deadlock.patch</span><br><span>new file mode 100644</span><br><span>index 0000000..a9aca5b</span><br><span>--- /dev/null</span><br><span>+++ b/third-party/pjproject/patches/0110_fix_tdata_rexmit_deadlock.patch</span><br><span>@@ -0,0 +1,203 @@</span><br><span style="color: hsl(120, 100%, 40%);">+From 3c9ad14b32ddb881559c05ea742aba3153a8cb8f Mon Sep 17 00:00:00 2001</span><br><span style="color: hsl(120, 100%, 40%);">+From: Riza Sulistyo <riza@teluu.com></span><br><span style="color: hsl(120, 100%, 40%);">+Date: Wed, 1 Aug 2018 10:49:51 -0500</span><br><span style="color: hsl(120, 100%, 40%);">+Subject: [PATCH] r5851 svn backport sip_inv.c: Fix race condition in 183</span><br><span style="color: hsl(120, 100%, 40%);">+ re-transmission deadlock</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+Fixed #2137: Race condition in 183 re-transmission can result in a deadlock.</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+The tdata containing the response can be shared by both the dialog</span><br><span style="color: hsl(120, 100%, 40%);">+object and the tsx object.  In order to prevent the race condition</span><br><span style="color: hsl(120, 100%, 40%);">+between the tsx retransmission and the dialog sending a response,</span><br><span style="color: hsl(120, 100%, 40%);">+clone the tdata before modifying it for the dialog send response.</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ASTERISK-27966</span><br><span style="color: hsl(120, 100%, 40%);">+---</span><br><span style="color: hsl(120, 100%, 40%);">+ pjsip/include/pjsip/sip_transport.h | 16 +++++++++++++</span><br><span style="color: hsl(120, 100%, 40%);">+ pjsip/src/pjsip-ua/sip_100rel.c     | 43 +--------------------------------</span><br><span style="color: hsl(120, 100%, 40%);">+ pjsip/src/pjsip-ua/sip_inv.c        | 14 ++++++++++-</span><br><span style="color: hsl(120, 100%, 40%);">+ pjsip/src/pjsip/sip_transport.c     | 47 +++++++++++++++++++++++++++++++++++++</span><br><span style="color: hsl(120, 100%, 40%);">+ 4 files changed, 77 insertions(+), 43 deletions(-)</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+diff --git a/pjsip/include/pjsip/sip_transport.h b/pjsip/include/pjsip/sip_transport.h</span><br><span style="color: hsl(120, 100%, 40%);">+index 10a50ef..36581dc 100644</span><br><span style="color: hsl(120, 100%, 40%);">+--- a/pjsip/include/pjsip/sip_transport.h</span><br><span>++++ b/pjsip/include/pjsip/sip_transport.h</span><br><span style="color: hsl(120, 100%, 40%);">+@@ -721,6 +721,22 @@ PJ_DECL(char*) pjsip_tx_data_get_info( pjsip_tx_data *tdata );</span><br><span style="color: hsl(120, 100%, 40%);">+ PJ_DECL(pj_status_t) pjsip_tx_data_set_transport(pjsip_tx_data *tdata,</span><br><span style="color: hsl(120, 100%, 40%);">+                                           const pjsip_tpselector *sel);</span><br><span style="color: hsl(120, 100%, 40%);">+ </span><br><span style="color: hsl(120, 100%, 40%);">++/**</span><br><span style="color: hsl(120, 100%, 40%);">++ * Clone pjsip_tx_data. This will duplicate the message contents of</span><br><span style="color: hsl(120, 100%, 40%);">++ * pjsip_tx_data (pjsip_tx_data.msg) and add reference count to the tdata.</span><br><span style="color: hsl(120, 100%, 40%);">++ * Once application has finished using the cloned pjsip_tx_data,</span><br><span style="color: hsl(120, 100%, 40%);">++ * it must release it by calling  #pjsip_tx_data_dec_ref().</span><br><span style="color: hsl(120, 100%, 40%);">++ * Currently, this will only clone response message.</span><br><span style="color: hsl(120, 100%, 40%);">++ *</span><br><span style="color: hsl(120, 100%, 40%);">++ * @param src     The source to be cloned.</span><br><span style="color: hsl(120, 100%, 40%);">++ * @param flags      Optional flags. Must be zero for now.</span><br><span style="color: hsl(120, 100%, 40%);">++ * @param p_rdata   Pointer to receive the cloned tdata.</span><br><span style="color: hsl(120, 100%, 40%);">++ *</span><br><span style="color: hsl(120, 100%, 40%);">++ * @return      PJ_SUCCESS on success or the appropriate error.</span><br><span style="color: hsl(120, 100%, 40%);">++ */</span><br><span style="color: hsl(120, 100%, 40%);">++PJ_DECL(pj_status_t) pjsip_tx_data_clone(const pjsip_tx_data *src,</span><br><span style="color: hsl(120, 100%, 40%);">++                                         unsigned flags,</span><br><span style="color: hsl(120, 100%, 40%);">++                                         pjsip_tx_data **p_rdata);</span><br><span style="color: hsl(120, 100%, 40%);">+ </span><br><span style="color: hsl(120, 100%, 40%);">+ /*****************************************************************************</span><br><span style="color: hsl(120, 100%, 40%);">+  *</span><br><span style="color: hsl(120, 100%, 40%);">+diff --git a/pjsip/src/pjsip-ua/sip_100rel.c b/pjsip/src/pjsip-ua/sip_100rel.c</span><br><span style="color: hsl(120, 100%, 40%);">+index eb9e587..7bf0ad1 100644</span><br><span style="color: hsl(120, 100%, 40%);">+--- a/pjsip/src/pjsip-ua/sip_100rel.c</span><br><span>++++ b/pjsip/src/pjsip-ua/sip_100rel.c</span><br><span style="color: hsl(120, 100%, 40%);">+@@ -634,47 +634,6 @@ static void on_retransmit(pj_timer_heap_t *timer_heap,</span><br><span style="color: hsl(120, 100%, 40%);">+ }</span><br><span style="color: hsl(120, 100%, 40%);">+ </span><br><span style="color: hsl(120, 100%, 40%);">+ </span><br><span style="color: hsl(120, 100%, 40%);">+-/* Clone response. */</span><br><span style="color: hsl(120, 100%, 40%);">+-static pjsip_tx_data *clone_tdata(dlg_data *dd,</span><br><span style="color: hsl(120, 100%, 40%);">+-                                const pjsip_tx_data *src)</span><br><span style="color: hsl(120, 100%, 40%);">+-{</span><br><span style="color: hsl(120, 100%, 40%);">+-    pjsip_tx_data *dst;</span><br><span style="color: hsl(120, 100%, 40%);">+-    const pjsip_hdr *hsrc;</span><br><span style="color: hsl(120, 100%, 40%);">+-    pjsip_msg *msg;</span><br><span style="color: hsl(120, 100%, 40%);">+-    pj_status_t status;</span><br><span style="color: hsl(120, 100%, 40%);">+-</span><br><span style="color: hsl(120, 100%, 40%);">+-    status = pjsip_endpt_create_tdata(dd->inv->dlg->endpt, &dst);</span><br><span style="color: hsl(120, 100%, 40%);">+-    if (status != PJ_SUCCESS)</span><br><span style="color: hsl(120, 100%, 40%);">+-   return NULL;</span><br><span style="color: hsl(120, 100%, 40%);">+-</span><br><span style="color: hsl(120, 100%, 40%);">+-    msg = pjsip_msg_create(dst->pool, PJSIP_RESPONSE_MSG);</span><br><span style="color: hsl(120, 100%, 40%);">+-    dst->msg = msg;</span><br><span style="color: hsl(120, 100%, 40%);">+-    pjsip_tx_data_add_ref(dst);</span><br><span style="color: hsl(120, 100%, 40%);">+-</span><br><span style="color: hsl(120, 100%, 40%);">+-    /* Duplicate status line */</span><br><span style="color: hsl(120, 100%, 40%);">+-    msg->line.status.code = src->msg->line.status.code;</span><br><span style="color: hsl(120, 100%, 40%);">+-    pj_strdup(dst->pool, &msg->line.status.reason, </span><br><span style="color: hsl(120, 100%, 40%);">+-         &src->msg->line.status.reason);</span><br><span style="color: hsl(120, 100%, 40%);">+-</span><br><span style="color: hsl(120, 100%, 40%);">+-    /* Duplicate all headers */</span><br><span style="color: hsl(120, 100%, 40%);">+-    hsrc = src->msg->hdr.next;</span><br><span style="color: hsl(120, 100%, 40%);">+-    while (hsrc != &src->msg->hdr) {</span><br><span style="color: hsl(120, 100%, 40%);">+- pjsip_hdr *h = (pjsip_hdr*) pjsip_hdr_clone(dst->pool, hsrc);</span><br><span style="color: hsl(120, 100%, 40%);">+-     pjsip_msg_add_hdr(msg, h);</span><br><span style="color: hsl(120, 100%, 40%);">+-   hsrc = hsrc->next;</span><br><span style="color: hsl(120, 100%, 40%);">+-    }</span><br><span style="color: hsl(120, 100%, 40%);">+-</span><br><span style="color: hsl(120, 100%, 40%);">+-    /* Duplicate message body */</span><br><span style="color: hsl(120, 100%, 40%);">+-    if (src->msg->body)</span><br><span style="color: hsl(120, 100%, 40%);">+-  msg->body = pjsip_msg_body_clone(dst->pool, src->msg->body);</span><br><span style="color: hsl(120, 100%, 40%);">+-</span><br><span style="color: hsl(120, 100%, 40%);">+-    PJ_LOG(5,(dd->inv->dlg->obj_name,</span><br><span style="color: hsl(120, 100%, 40%);">+-      "Reliable response %s created",</span><br><span style="color: hsl(120, 100%, 40%);">+-            pjsip_tx_data_get_info(dst)));</span><br><span style="color: hsl(120, 100%, 40%);">+-</span><br><span style="color: hsl(120, 100%, 40%);">+-    return dst;</span><br><span style="color: hsl(120, 100%, 40%);">+-}</span><br><span style="color: hsl(120, 100%, 40%);">+-</span><br><span style="color: hsl(120, 100%, 40%);">+ </span><br><span style="color: hsl(120, 100%, 40%);">+ /* Check if any pending response in transmission list has SDP */</span><br><span style="color: hsl(120, 100%, 40%);">+ static pj_bool_t has_sdp(dlg_data *dd)</span><br><span style="color: hsl(120, 100%, 40%);">+@@ -725,7 +684,7 @@ PJ_DEF(pj_status_t) pjsip_100rel_tx_response(pjsip_inv_session *inv,</span><br><span style="color: hsl(120, 100%, 40%);">+      * if it wants to send another response.</span><br><span style="color: hsl(120, 100%, 40%);">+      */</span><br><span style="color: hsl(120, 100%, 40%);">+     old_tdata = tdata;</span><br><span style="color: hsl(120, 100%, 40%);">+-    tdata = clone_tdata(dd, old_tdata);</span><br><span style="color: hsl(120, 100%, 40%);">++    pjsip_tx_data_clone(old_tdata, 0, &tdata);</span><br><span style="color: hsl(120, 100%, 40%);">+     pjsip_tx_data_dec_ref(old_tdata);</span><br><span style="color: hsl(120, 100%, 40%);">+     </span><br><span style="color: hsl(120, 100%, 40%);">+ </span><br><span style="color: hsl(120, 100%, 40%);">+diff --git a/pjsip/src/pjsip-ua/sip_inv.c b/pjsip/src/pjsip-ua/sip_inv.c</span><br><span style="color: hsl(120, 100%, 40%);">+index 16a0e17..da28903 100644</span><br><span style="color: hsl(120, 100%, 40%);">+--- a/pjsip/src/pjsip-ua/sip_inv.c</span><br><span>++++ b/pjsip/src/pjsip-ua/sip_inv.c</span><br><span style="color: hsl(120, 100%, 40%);">+@@ -2382,6 +2382,7 @@ PJ_DEF(pj_status_t) pjsip_inv_answer(     pjsip_inv_session *inv,</span><br><span style="color: hsl(120, 100%, 40%);">+                                       pjsip_tx_data **p_tdata )</span><br><span style="color: hsl(120, 100%, 40%);">+ {</span><br><span style="color: hsl(120, 100%, 40%);">+     pjsip_tx_data *last_res;</span><br><span style="color: hsl(120, 100%, 40%);">++    pjsip_tx_data *old_res;</span><br><span style="color: hsl(120, 100%, 40%);">+     pj_status_t status;</span><br><span style="color: hsl(120, 100%, 40%);">+ </span><br><span style="color: hsl(120, 100%, 40%);">+     /* Verify arguments. */</span><br><span style="color: hsl(120, 100%, 40%);">+@@ -2397,8 +2398,19 @@ PJ_DEF(pj_status_t) pjsip_inv_answer(     pjsip_inv_session *inv,</span><br><span style="color: hsl(120, 100%, 40%);">+ </span><br><span style="color: hsl(120, 100%, 40%);">+     pjsip_dlg_inc_lock(inv->dlg);</span><br><span style="color: hsl(120, 100%, 40%);">+ </span><br><span style="color: hsl(120, 100%, 40%);">++    /* Clone last response.</span><br><span style="color: hsl(120, 100%, 40%);">++     * The tdata (last_answer) is a shared object used by the transaction.</span><br><span style="color: hsl(120, 100%, 40%);">++     * Modifying a shared object might lead to a deadlock.</span><br><span style="color: hsl(120, 100%, 40%);">++     * Refer to ticket #2137 for more detail.</span><br><span style="color: hsl(120, 100%, 40%);">++     */</span><br><span style="color: hsl(120, 100%, 40%);">++    status = pjsip_tx_data_clone(inv->last_answer, 0, &last_res);</span><br><span style="color: hsl(120, 100%, 40%);">++    if (status != PJ_SUCCESS)</span><br><span style="color: hsl(120, 100%, 40%);">++    goto on_return;</span><br><span style="color: hsl(120, 100%, 40%);">++    old_res = inv->last_answer;</span><br><span style="color: hsl(120, 100%, 40%);">++    inv->last_answer = last_res;</span><br><span style="color: hsl(120, 100%, 40%);">++    pjsip_tx_data_dec_ref(old_res);</span><br><span style="color: hsl(120, 100%, 40%);">++</span><br><span style="color: hsl(120, 100%, 40%);">+     /* Modify last response. */</span><br><span style="color: hsl(120, 100%, 40%);">+-    last_res = inv->last_answer;</span><br><span style="color: hsl(120, 100%, 40%);">+     status = pjsip_dlg_modify_response(inv->dlg, last_res, st_code, st_text);</span><br><span style="color: hsl(120, 100%, 40%);">+     if (status != PJ_SUCCESS)</span><br><span style="color: hsl(120, 100%, 40%);">+        goto on_return;</span><br><span style="color: hsl(120, 100%, 40%);">+diff --git a/pjsip/src/pjsip/sip_transport.c b/pjsip/src/pjsip/sip_transport.c</span><br><span style="color: hsl(120, 100%, 40%);">+index f350fe7..3a8baca 100644</span><br><span style="color: hsl(120, 100%, 40%);">+--- a/pjsip/src/pjsip/sip_transport.c</span><br><span>++++ b/pjsip/src/pjsip/sip_transport.c</span><br><span style="color: hsl(120, 100%, 40%);">+@@ -643,6 +643,53 @@ PJ_DEF(pj_status_t) pjsip_tx_data_set_transport(pjsip_tx_data *tdata,</span><br><span style="color: hsl(120, 100%, 40%);">+     return PJ_SUCCESS;</span><br><span style="color: hsl(120, 100%, 40%);">+ }</span><br><span style="color: hsl(120, 100%, 40%);">+ </span><br><span style="color: hsl(120, 100%, 40%);">++/* Clone pjsip_tx_data. */</span><br><span style="color: hsl(120, 100%, 40%);">++PJ_DEF(pj_status_t) pjsip_tx_data_clone(const pjsip_tx_data *src,</span><br><span style="color: hsl(120, 100%, 40%);">++                                        unsigned flags,</span><br><span style="color: hsl(120, 100%, 40%);">++                                        pjsip_tx_data ** p_tdata)</span><br><span style="color: hsl(120, 100%, 40%);">++{</span><br><span style="color: hsl(120, 100%, 40%);">++    pjsip_tx_data *dst;</span><br><span style="color: hsl(120, 100%, 40%);">++    const pjsip_hdr *hsrc;</span><br><span style="color: hsl(120, 100%, 40%);">++    pjsip_msg *msg;</span><br><span style="color: hsl(120, 100%, 40%);">++    pj_status_t status;</span><br><span style="color: hsl(120, 100%, 40%);">++</span><br><span style="color: hsl(120, 100%, 40%);">++    PJ_UNUSED_ARG(flags);</span><br><span style="color: hsl(120, 100%, 40%);">++</span><br><span style="color: hsl(120, 100%, 40%);">++    status = pjsip_tx_data_create(src->mgr, p_tdata);</span><br><span style="color: hsl(120, 100%, 40%);">++    if (status != PJ_SUCCESS)</span><br><span style="color: hsl(120, 100%, 40%);">++    return status;</span><br><span style="color: hsl(120, 100%, 40%);">++</span><br><span style="color: hsl(120, 100%, 40%);">++    dst = *p_tdata;</span><br><span style="color: hsl(120, 100%, 40%);">++</span><br><span style="color: hsl(120, 100%, 40%);">++    msg = pjsip_msg_create(dst->pool, PJSIP_RESPONSE_MSG);</span><br><span style="color: hsl(120, 100%, 40%);">++    dst->msg = msg;</span><br><span style="color: hsl(120, 100%, 40%);">++    pjsip_tx_data_add_ref(dst);</span><br><span style="color: hsl(120, 100%, 40%);">++</span><br><span style="color: hsl(120, 100%, 40%);">++    /* Duplicate status line */</span><br><span style="color: hsl(120, 100%, 40%);">++    msg->line.status.code = src->msg->line.status.code;</span><br><span style="color: hsl(120, 100%, 40%);">++    pj_strdup(dst->pool, &msg->line.status.reason,</span><br><span style="color: hsl(120, 100%, 40%);">++       &src->msg->line.status.reason);</span><br><span style="color: hsl(120, 100%, 40%);">++</span><br><span style="color: hsl(120, 100%, 40%);">++    /* Duplicate all headers */</span><br><span style="color: hsl(120, 100%, 40%);">++    hsrc = src->msg->hdr.next;</span><br><span style="color: hsl(120, 100%, 40%);">++    while (hsrc != &src->msg->hdr) {</span><br><span style="color: hsl(120, 100%, 40%);">++ pjsip_hdr *h = (pjsip_hdr*) pjsip_hdr_clone(dst->pool, hsrc);</span><br><span style="color: hsl(120, 100%, 40%);">++     pjsip_msg_add_hdr(msg, h);</span><br><span style="color: hsl(120, 100%, 40%);">++   hsrc = hsrc->next;</span><br><span style="color: hsl(120, 100%, 40%);">++    }</span><br><span style="color: hsl(120, 100%, 40%);">++</span><br><span style="color: hsl(120, 100%, 40%);">++    /* Duplicate message body */</span><br><span style="color: hsl(120, 100%, 40%);">++    if (src->msg->body)</span><br><span style="color: hsl(120, 100%, 40%);">++  msg->body = pjsip_msg_body_clone(dst->pool, src->msg->body);</span><br><span style="color: hsl(120, 100%, 40%);">++</span><br><span style="color: hsl(120, 100%, 40%);">++    dst->is_pending = src->is_pending;</span><br><span style="color: hsl(120, 100%, 40%);">++</span><br><span style="color: hsl(120, 100%, 40%);">++    PJ_LOG(5,(THIS_FILE,</span><br><span style="color: hsl(120, 100%, 40%);">++          "Tx data %s cloned",</span><br><span style="color: hsl(120, 100%, 40%);">++       pjsip_tx_data_get_info(dst)));</span><br><span style="color: hsl(120, 100%, 40%);">++</span><br><span style="color: hsl(120, 100%, 40%);">++    return PJ_SUCCESS;</span><br><span style="color: hsl(120, 100%, 40%);">++}</span><br><span style="color: hsl(120, 100%, 40%);">+ </span><br><span style="color: hsl(120, 100%, 40%);">+ PJ_DEF(char*) pjsip_rx_data_get_info(pjsip_rx_data *rdata)</span><br><span style="color: hsl(120, 100%, 40%);">+ {</span><br><span style="color: hsl(120, 100%, 40%);">+-- </span><br><span style="color: hsl(120, 100%, 40%);">+2.7.4</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span></span><br></pre><p>To view, visit <a href="https://gerrit.asterisk.org/9800">change 9800</a>. To unsubscribe, or for help writing mail filters, 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/9800"/><meta itemprop="name" content="View Change"/></div></div>

<div style="display:none"> Gerrit-Project: asterisk </div>
<div style="display:none"> Gerrit-Branch: 16 </div>
<div style="display:none"> Gerrit-MessageType: merged </div>
<div style="display:none"> Gerrit-Change-Id: Ic381004a3a212fe1d8eca0e707fe09dba4a6ab4e </div>
<div style="display:none"> Gerrit-Change-Number: 9800 </div>
<div style="display:none"> Gerrit-PatchSet: 2 </div>
<div style="display:none"> Gerrit-Owner: Torrey Searle <tsearle@gmail.com> </div>
<div style="display:none"> Gerrit-Reviewer: Jenkins2 </div>
<div style="display:none"> Gerrit-Reviewer: Joshua Colp <jcolp@digium.com> </div>
<div style="display:none"> Gerrit-Reviewer: Richard Mudgett <rmudgett@digium.com> </div>