<p>Joshua Colp <strong>merged</strong> this change.</p><p><a href="https://gerrit.asterisk.org/7084">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;">res_pjsip_session: Fix multiple leaks.<br><br>* Pre-initialize cloned media state vectors to final size to ensure<br>  vector errors cannot happen later in the clone initialization.<br>* Release session_media on vector replace failure in<br>  ast_sip_session_media_state_add.<br>* Release clone and media_state in ast_sip_session_refresh if we fail to<br>  append to the stream topology, return an error.<br><br>Change-Id: Ib5ffc9b198683fa7e9bf166d74d30c1334c23acb<br>---<br>M res/res_pjsip_session.c<br>1 file changed, 23 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 4724d46..dda0421 100644<br>--- a/res/res_pjsip_session.c<br>+++ b/res/res_pjsip_session.c<br>@@ -174,7 +174,8 @@<br>      ao2_callback_data(sdp_handlers, OBJ_KEY | OBJ_UNLINK | OBJ_NODATA, remove_handler, (void *)stream_type, handler);<br> }<br> <br>-struct ast_sip_session_media_state *ast_sip_session_media_state_alloc(void)<br>+static struct ast_sip_session_media_state *internal_sip_session_media_state_alloc(<br>+  size_t sessions, size_t read_callbacks)<br> {<br>   struct ast_sip_session_media_state *media_state;<br> <br>@@ -183,18 +184,24 @@<br>            return NULL;<br>  }<br> <br>- if (AST_VECTOR_INIT(&media_state->sessions, DEFAULT_NUM_SESSION_MEDIA) < 0) {<br>+      if (AST_VECTOR_INIT(&media_state->sessions, sessions) < 0) {<br>                ast_free(media_state);<br>                return NULL;<br>  }<br> <br>- if (AST_VECTOR_INIT(&media_state->read_callbacks, DEFAULT_NUM_SESSION_MEDIA) < 0) {<br>+        if (AST_VECTOR_INIT(&media_state->read_callbacks, read_callbacks) < 0) {<br>            AST_VECTOR_FREE(&media_state->sessions);<br>               ast_free(media_state);<br>                return NULL;<br>  }<br> <br>  return media_state;<br>+}<br>+<br>+struct ast_sip_session_media_state *ast_sip_session_media_state_alloc(void)<br>+{<br>+ return internal_sip_session_media_state_alloc(<br>+               DEFAULT_NUM_SESSION_MEDIA, DEFAULT_NUM_SESSION_MEDIA);<br> }<br> <br> void ast_sip_session_media_state_reset(struct ast_sip_session_media_state *media_state)<br>@@ -225,7 +232,9 @@<br>          return NULL;<br>  }<br> <br>- cloned = ast_sip_session_media_state_alloc();<br>+        cloned = internal_sip_session_media_state_alloc(<br>+             AST_VECTOR_SIZE(&media_state->sessions),<br>+              AST_VECTOR_SIZE(&media_state->read_callbacks));<br>        if (!cloned) {<br>                return NULL;<br>  }<br>@@ -452,7 +461,11 @@<br>               }<br>     }<br> <br>- AST_VECTOR_REPLACE(&media_state->sessions, position, session_media);<br>+  if (AST_VECTOR_REPLACE(&media_state->sessions, position, session_media)) {<br>+            ao2_ref(session_media, -1);<br>+<br>+               return NULL;<br>+ }<br> <br>  /* If this stream will be active in some way and it is the first of this type then consider this the default media session to match */<br>        if (!media_state->default_session[type] && ast_stream_get_state(ast_stream_topology_get_stream(media_state->topology, position)) != AST_STREAM_STATE_REMOVED) {<br>@@ -1588,7 +1601,11 @@<br>                                         }<br> <br>                                  ast_stream_set_state(cloned, AST_STREAM_STATE_REMOVED);<br>-                                      ast_stream_topology_append_stream(media_state->topology, cloned);<br>+                                 if (ast_stream_topology_append_stream(media_state->topology, cloned) < 0) {<br>+                                            ast_stream_free(cloned);<br>+                                             ast_sip_session_media_state_free(media_state);<br>+                                               return -1;<br>+                                   }<br>                             }<br> <br>                          /* If the resulting media state matches the existing active state don't bother doing a session refresh */<br></pre><p>To view, visit <a href="https://gerrit.asterisk.org/7084">change 7084</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/7084"/><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: Ib5ffc9b198683fa7e9bf166d74d30c1334c23acb </div>
<div style="display:none"> Gerrit-Change-Number: 7084 </div>
<div style="display:none"> Gerrit-PatchSet: 3 </div>
<div style="display:none"> Gerrit-Owner: Corey Farrell <git@cfware.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>