From ca02121ef7f5a521dd941ca758750a074b9fbac8 Mon Sep 17 00:00:00 2001
From: Kevin Harwell <kharwell@digium.com>
Date: Fri, 23 Jan 2015 15:21:56 +0000
Subject: [PATCH] Investigate and fix memory leaks in Asterisk

Fixed memory leaks that were found in Asterisk.

ASTERISK-24693 #close
Reported by:  Kevin Harwell
Review: https://reviewboard.asterisk.org/r/4347/
........

Merged revisions 430999 from http://svn.asterisk.org/svn/asterisk/branches/13


git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@431010 65c4cc65-6c06-0410-ace0-fbb531ad65f3
---
 channels/chan_iax2.c                      | 6 ++++--
 include/asterisk/stasis_app.h             | 3 +--
 res/parking/parking_applications.c        | 1 +
 res/res_ari_channels.c                    | 4 ++--
 res/res_ari_endpoints.c                   | 4 ++--
 res/res_ari_events.c                      | 2 +-
 res/res_pjsip/pjsip_global_headers.c      | 1 +
 res/res_pjsip_mwi.c                       | 2 +-
 res/res_pjsip_pubsub.c                    | 4 +---
 res/res_stasis.c                          | 2 ++
 rest-api-templates/param_parsing.mustache | 2 +-
 11 files changed, 17 insertions(+), 14 deletions(-)

diff --git a/channels/chan_iax2.c b/channels/chan_iax2.c
index cc70bfd3a9..b0c426fe14 100644
--- a/channels/chan_iax2.c
+++ b/channels/chan_iax2.c
@@ -4364,7 +4364,7 @@ static struct iax2_peer *realtime_peer(const char *peername, struct ast_sockaddr
 		if (var && !ast_sockaddr_isnull(addr)) {
 			for (tmp = var; tmp; tmp = tmp->next) {
 				if (!strcasecmp(tmp->name, "host")) {
-					struct ast_sockaddr *hostaddr;
+					struct ast_sockaddr *hostaddr = NULL;
 
 					if (!ast_sockaddr_resolve(&hostaddr, tmp->value, PARSE_PORT_FORBID, AST_AF_UNSPEC)
 						|| ast_sockaddr_cmp_addr(hostaddr, addr)) {
@@ -4372,6 +4372,7 @@ static struct iax2_peer *realtime_peer(const char *peername, struct ast_sockaddr
 						ast_variables_destroy(var);
 						var = NULL;
 					}
+					ast_free(hostaddr);
 					break;
 				}
 			}
@@ -4486,7 +4487,7 @@ static struct iax2_user *realtime_user(const char *username, struct ast_sockaddr
 		if (var) {
 			for (tmp = var; tmp; tmp = tmp->next) {
 				if (!strcasecmp(tmp->name, "host")) {
-					struct ast_sockaddr *hostaddr;
+					struct ast_sockaddr *hostaddr = NULL;
 
 					if (!ast_sockaddr_resolve(&hostaddr, tmp->value, PARSE_PORT_FORBID, AST_AF_UNSPEC)
 						|| ast_sockaddr_cmp_addr(hostaddr, addr)) {
@@ -4494,6 +4495,7 @@ static struct iax2_user *realtime_user(const char *username, struct ast_sockaddr
 						ast_variables_destroy(var);
 						var = NULL;
 					}
+					ast_free(hostaddr);
 					break;
 				}
 			}
diff --git a/include/asterisk/stasis_app.h b/include/asterisk/stasis_app.h
index e472754801..0d04caa3db 100644
--- a/include/asterisk/stasis_app.h
+++ b/include/asterisk/stasis_app.h
@@ -245,8 +245,7 @@ enum stasis_app_user_event_res {
  * \param event_name Name of the Userevent.
  * \param source_uris URIs for the source objects to attach to event.
  * \param sources_count Array size of source_uris.
- * \param userevent_data Custom parameters for the user event
- * \param userevents_count Array size of userevent_data
+ * \param json_variables event blob variables.
  *
  * \return \ref stasis_app_user_event_res return code.
  */
diff --git a/res/parking/parking_applications.c b/res/parking/parking_applications.c
index c5214b36a3..002d60a765 100644
--- a/res/parking/parking_applications.c
+++ b/res/parking/parking_applications.c
@@ -610,6 +610,7 @@ static int parked_call_app_exec(struct ast_channel *chan, const char *data)
 	}
 
 	/* The parked call needs to know who is retrieving it before we move it out of the parking bridge */
+	ast_assert(pu->retriever == NULL);
 	pu->retriever = ast_channel_snapshot_create(chan);
 
 	/* Create bridge */
diff --git a/res/res_ari_channels.c b/res/res_ari_channels.c
index 82bb662d27..20128ae02f 100644
--- a/res/res_ari_channels.c
+++ b/res/res_ari_channels.c
@@ -233,7 +233,7 @@ static void ast_ari_channels_originate_cb(
 			goto fin;
 		}
 	}
-	args.variables = ast_json_ref(body);
+	args.variables = body;
 	ast_ari_channels_originate(headers, &args, response);
 #if defined(AST_DEVMODE)
 	code = response->response_code;
@@ -456,7 +456,7 @@ static void ast_ari_channels_originate_with_id_cb(
 			goto fin;
 		}
 	}
-	args.variables = ast_json_ref(body);
+	args.variables = body;
 	ast_ari_channels_originate_with_id(headers, &args, response);
 #if defined(AST_DEVMODE)
 	code = response->response_code;
diff --git a/res/res_ari_endpoints.c b/res/res_ari_endpoints.c
index 071d66bec4..3ebe668585 100644
--- a/res/res_ari_endpoints.c
+++ b/res/res_ari_endpoints.c
@@ -170,7 +170,7 @@ static void ast_ari_endpoints_send_message_cb(
 			goto fin;
 		}
 	}
-	args.variables = ast_json_ref(body);
+	args.variables = body;
 	ast_ari_endpoints_send_message(headers, &args, response);
 #if defined(AST_DEVMODE)
 	code = response->response_code;
@@ -396,7 +396,7 @@ static void ast_ari_endpoints_send_message_to_endpoint_cb(
 			goto fin;
 		}
 	}
-	args.variables = ast_json_ref(body);
+	args.variables = body;
 	ast_ari_endpoints_send_message_to_endpoint(headers, &args, response);
 #if defined(AST_DEVMODE)
 	code = response->response_code;
diff --git a/res/res_ari_events.c b/res/res_ari_events.c
index 2a596d0a8c..c601f571fa 100644
--- a/res/res_ari_events.c
+++ b/res/res_ari_events.c
@@ -281,7 +281,7 @@ static void ast_ari_events_user_event_cb(
 			goto fin;
 		}
 	}
-	args.variables = ast_json_ref(body);
+	args.variables = body;
 	ast_ari_events_user_event(headers, &args, response);
 #if defined(AST_DEVMODE)
 	code = response->response_code;
diff --git a/res/res_pjsip/pjsip_global_headers.c b/res/res_pjsip/pjsip_global_headers.c
index eff8703149..0fcc3a1398 100644
--- a/res/res_pjsip/pjsip_global_headers.c
+++ b/res/res_pjsip/pjsip_global_headers.c
@@ -111,6 +111,7 @@ static void remove_header(struct header_list *headers, const char *to_remove)
 	AST_LIST_TRAVERSE_SAFE_BEGIN(headers, iter, next) {
 		if (!strcasecmp(iter->name, to_remove)) {
 			AST_LIST_REMOVE_CURRENT(next);
+			destroy_header(iter);
 			break;
 		}
 	}
diff --git a/res/res_pjsip_mwi.c b/res/res_pjsip_mwi.c
index 8a61659916..9c275af468 100644
--- a/res/res_pjsip_mwi.c
+++ b/res/res_pjsip_mwi.c
@@ -658,7 +658,7 @@ static struct mwi_subscription *mwi_subscribe_all(
 static int mwi_new_subscribe(struct ast_sip_endpoint *endpoint,
 		const char *resource)
 {
-	struct ast_sip_aor *aor;
+	RAII_VAR(struct ast_sip_aor *, aor, NULL, ao2_cleanup);
 
 	if (ast_strlen_zero(resource)) {
 		if (ast_sip_for_each_aor(endpoint->aors, mwi_validate_for_aor, endpoint)) {
diff --git a/res/res_pjsip_pubsub.c b/res/res_pjsip_pubsub.c
index 3f3fb9b9c4..5047184f83 100644
--- a/res/res_pjsip_pubsub.c
+++ b/res/res_pjsip_pubsub.c
@@ -949,7 +949,7 @@ static void resource_tree_destroy(struct resource_tree *tree)
 static int build_resource_tree(struct ast_sip_endpoint *endpoint, const struct ast_sip_subscription_handler *handler,
 		const char *resource, struct resource_tree *tree, int has_eventlist_support)
 {
-	struct resource_list *list;
+	RAII_VAR(struct resource_list *, list, NULL, ao2_cleanup);
 	struct resources visited;
 
 	if (!has_eventlist_support || !(list = retrieve_resource_list(resource, handler->event_name))) {
@@ -975,7 +975,6 @@ static int build_resource_tree(struct ast_sip_endpoint *endpoint, const struct a
 
 	build_node_children(endpoint, handler, list, tree->root, &visited);
 	AST_VECTOR_FREE(&visited);
-	ao2_cleanup(list);
 
 	if (AST_VECTOR_SIZE(&tree->root->children) > 0) {
 		return 200;
@@ -3183,7 +3182,6 @@ static int serialized_pubsub_on_client_refresh(void *userdata)
 		pjsip_evsub_send_request(sub_tree->evsub, tdata);
 	} else {
 		pjsip_evsub_terminate(sub_tree->evsub, PJ_TRUE);
-		return 0;
 	}
 	ao2_cleanup(sub_tree);
 	return 0;
diff --git a/res/res_stasis.c b/res/res_stasis.c
index 0bf7b58717..6794adedb4 100644
--- a/res/res_stasis.c
+++ b/res/res_stasis.c
@@ -1817,6 +1817,8 @@ enum stasis_app_user_event_res stasis_app_user_event(const char *app_name,
 	blob = json_variables;
 	if (!blob) {
 		blob = ast_json_pack("{}");
+	} else {
+		ast_json_ref(blob);
 	}
 	json_value = ast_json_string_create(event_name);
 	if (!json_value) {
diff --git a/rest-api-templates/param_parsing.mustache b/rest-api-templates/param_parsing.mustache
index 2dde4b33fa..247c121d9c 100644
--- a/rest-api-templates/param_parsing.mustache
+++ b/rest-api-templates/param_parsing.mustache
@@ -101,7 +101,7 @@
 		}
 	}
 {{#body_parameter}}
-	args.{{c_name}} = ast_json_ref(body);
+	args.{{c_name}} = body;
 {{/body_parameter}}
 {{^body_parameter}}
 	if (ast_ari_{{c_name}}_{{c_nickname}}_parse_body(body, &args)) {
-- 
GitLab