<p>Joshua Colp <strong>merged</strong> this change.</p><p><a href="https://gerrit.asterisk.org/6278">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_session.c: Fix crash when declining an active stream.<br><br>If a previously active stream is declined we could crash because the<br>channel's thread is still using the stream while we are updating the<br>topology in the serializer thread.<br><br>* Defer removing any declined stream's handler until we have blocked the<br>channel's thread with the channel lock.<br><br>ASTERISK-27212<br><br>Change-Id: I50e1d3ef26f8e41948f4c411ee329aa3b960a420<br>---<br>M res/res_pjsip_session.c<br>1 file changed, 32 insertions(+), 6 deletions(-)<br><br></pre><pre style="font-family: monospace,monospace; white-space: pre-wrap;">diff --git a/res/res_pjsip_session.c b/res/res_pjsip_session.c<br>index c4b0041..b6b8a21 100644<br>--- a/res/res_pjsip_session.c<br>+++ b/res/res_pjsip_session.c<br>@@ -784,12 +784,11 @@<br>               * we remove it as a result of the stream limit being reached.<br>                 */<br>           if (ast_stream_get_state(stream) == AST_STREAM_STATE_REMOVED) {<br>-                      /* This stream is no longer being used so release any resources the handler<br>-                   * may have on it.<br>+                   /*<br>+                    * Defer removing the handler until we are ready to activate<br>+                  * the new topology.  The channel's thread may still be using<br>+                     * the stream and we could crash before we are ready.<br>                          */<br>-                  if (session_media->handler) {<br>-                             session_media_set_handler(session_media, NULL);<br>-                      }<br>                     continue;<br>             }<br> <br>@@ -800,6 +799,32 @@<br> <br>         /* Apply the pending media state to the channel and make it active */<br>         ast_channel_lock(session->channel);<br>+<br>+    /* Now update the stream handler for any declined/removed streams */<br>+ for (i = 0; i < local->media_count; ++i) {<br>+             struct ast_sip_session_media *session_media;<br>+         struct ast_stream *stream;<br>+<br>+                if (!remote->media[i]) {<br>+                  continue;<br>+            }<br>+<br>+         ast_assert(i < AST_VECTOR_SIZE(&session->pending_media_state->sessions));<br>+               ast_assert(i < ast_stream_topology_get_count(session->pending_media_state->topology));<br>+<br>+           session_media = AST_VECTOR_GET(&session->pending_media_state->sessions, i);<br>+                stream = ast_stream_topology_get_stream(session->pending_media_state->topology, i);<br>+<br>+         if (ast_stream_get_state(stream) == AST_STREAM_STATE_REMOVED<br>+                 && session_media->handler) {<br>+                      /*<br>+                    * This stream is no longer being used and the channel's thread<br>+                   * is held off because we have the channel lock so release any<br>+                        * resources the handler may have on it.<br>+                      */<br>+                  session_media_set_handler(session_media, NULL);<br>+              }<br>+    }<br> <br>  /* Update the topology on the channel to match the accepted one */<br>    topology = ast_stream_topology_clone(session->pending_media_state->topology);<br>@@ -814,8 +839,9 @@<br> <br>   /* Add all the file descriptors from the pending media state */<br>       for (i = 0; i < AST_VECTOR_SIZE(&session->pending_media_state->read_callbacks); ++i) {<br>-          struct ast_sip_session_media_read_callback_state *callback_state = AST_VECTOR_GET_ADDR(&session->pending_media_state->read_callbacks, i);<br>+          struct ast_sip_session_media_read_callback_state *callback_state;<br> <br>+         callback_state = AST_VECTOR_GET_ADDR(&session->pending_media_state->read_callbacks, i);<br>             ast_channel_internal_fd_set(session->channel, i + AST_EXTENDED_FDS, callback_state->fd);<br>        }<br> <br></pre><p>To view, visit <a href="https://gerrit.asterisk.org/6278">change 6278</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/6278"/><meta itemprop="name" content="View Change"/></div></div>

<div style="display:none"> Gerrit-Project: asterisk </div>
<div style="display:none"> Gerrit-Branch: master </div>
<div style="display:none"> Gerrit-MessageType: merged </div>
<div style="display:none"> Gerrit-Change-Id: I50e1d3ef26f8e41948f4c411ee329aa3b960a420 </div>
<div style="display:none"> Gerrit-Change-Number: 6278 </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>