chan_sip: Fix reference leaks in error paths.
authorCorey Farrell <git@cfware.com>
Sat, 9 Jul 2016 18:32:27 +0000 (14:32 -0400)
committerCorey Farrell <git@cfware.com>
Sat, 9 Jul 2016 18:39:01 +0000 (13:39 -0500)
* get_sip_pvt_from_replaces leaks sip_pvt_ptr on any error.
* build_peer leaks peer on failure to allocate the endpoint.

This patch fixes get_sip_pvt by using an RAII_VAR, build_peer is fixed
with an unref in the appropriate place.

ASTERISK-26184 #close

Change-Id: I728b424648ad041409f7d90880f4c28b3ce2ca12

channels/chan_sip.c

index 28379ff..599ecd6 100644 (file)
@@ -18386,7 +18386,7 @@ static enum sip_get_dest_result get_destination(struct sip_pvt *p, struct sip_re
 static int get_sip_pvt_from_replaces(const char *callid, const char *totag,
                const char *fromtag, struct sip_pvt **out_pvt, struct ast_channel **out_chan)
 {
-       struct sip_pvt *sip_pvt_ptr;
+       RAII_VAR(struct sip_pvt *, sip_pvt_ptr, NULL, ao2_cleanup);
        struct sip_pvt tmp_dialog = {
                .callid = callid,
        };
@@ -18461,6 +18461,9 @@ static int get_sip_pvt_from_replaces(const char *callid, const char *totag,
                }
        }
 
+       /* If we're here sip_pvt_ptr has been copied to *out_pvt, prevent RAII_VAR cleanup */
+       sip_pvt_ptr = NULL;
+
        return 0;
 }
 
@@ -31095,6 +31098,7 @@ static struct sip_peer *build_peer(const char *name, struct ast_variable *v, str
                        return NULL;
                }
                if (!(peer->endpoint = ast_endpoint_create("SIP", name))) {
+                       ao2_t_ref(peer, -1, "failed to allocate endpoint, drop peer");
                        return NULL;
                }
                if (!(peer->caps = ast_format_cap_alloc(AST_FORMAT_CAP_FLAG_DEFAULT))) {