[asterisk-commits] coreyfarrell: branch 11 r428117 - /branches/11/channels/chan_sip.c

SVN commits to the Asterisk project asterisk-commits at lists.digium.com
Mon Nov 17 09:56:19 CST 2014


Author: coreyfarrell
Date: Mon Nov 17 09:56:11 2014
New Revision: 428117

URL: http://svnview.digium.com/svn/asterisk?view=rev&rev=428117
Log:
chan_sip: Fix theoretical leak of p->refer.

If transmit_refer is called when p->refer is already allocated,
it leaks the previous allocation.  Updated code to always free
previous allocation during a new allocation.  Also instead of
checking if we have a previous allocation, always create a
clean record.

ASTERISK-15242 #close
Reported by: David Woolley
Review: https://reviewboard.asterisk.org/r/4160/

Modified:
    branches/11/channels/chan_sip.c

Modified: branches/11/channels/chan_sip.c
URL: http://svnview.digium.com/svn/asterisk/branches/11/channels/chan_sip.c?view=diff&rev=428117&r1=428116&r2=428117
==============================================================================
--- branches/11/channels/chan_sip.c (original)
+++ branches/11/channels/chan_sip.c Mon Nov 17 09:56:11 2014
@@ -1431,6 +1431,7 @@
 static struct ast_channel *sip_pvt_lock_full(struct sip_pvt *pvt);
 /* static int sip_addrcmp(char *name, struct sockaddr_in *sin);	Support for peer matching */
 static int sip_refer_alloc(struct sip_pvt *p);
+static void sip_refer_destroy(struct sip_pvt *p);
 static int sip_notify_alloc(struct sip_pvt *p);
 static void ast_quiet_chan(struct ast_channel *chan);
 static int attempt_transfer(struct sip_dual *transferer, struct sip_dual *target);
@@ -6405,14 +6406,7 @@
 		ast_udptl_destroy(p->udptl);
 		p->udptl = NULL;
 	}
-	if (p->refer) {
-		if (p->refer->refer_call) {
-			p->refer->refer_call = dialog_unref(p->refer->refer_call, "unref dialog p->refer->refer_call");
-		}
-		ast_string_field_free_memory(p->refer);
-		ast_free(p->refer);
-		p->refer = NULL;
-	}
+	sip_refer_destroy(p);
 	if (p->route) {
 		free_old_route(p->route);
 		p->route = NULL;
@@ -15374,8 +15368,22 @@
 /*! \brief Allocate SIP refer structure */
 static int sip_refer_alloc(struct sip_pvt *p)
 {
+	sip_refer_destroy(p);
 	p->refer = ast_calloc_with_stringfields(1, struct sip_refer, 512);
 	return p->refer ? 1 : 0;
+}
+
+/*! \brief Destroy SIP refer structure */
+static void sip_refer_destroy(struct sip_pvt *p)
+{
+	if (p->refer) {
+		if (p->refer->refer_call) {
+			p->refer->refer_call = dialog_unref(p->refer->refer_call, "unref dialog p->refer->refer_call");
+		}
+		ast_string_field_free_memory(p->refer);
+		ast_free(p->refer);
+		p->refer = NULL;
+	}
 }
 
 /*! \brief Allocate SIP refer structure */
@@ -17862,8 +17870,9 @@
 	struct sip_refer *refer = NULL;
 	const char *transfer_context = NULL;
 
-	if (!p->refer && !sip_refer_alloc(p))
+	if (!sip_refer_alloc(p)) {
 		return -1;
+	}
 
 	refer = p->refer;
 
@@ -25342,7 +25351,7 @@
 		replace_id = ast_strdupa(p_replaces);
 		ast_uri_decode(replace_id, ast_uri_sip_user);
 
-		if (!p->refer && !sip_refer_alloc(p)) {
+		if (!sip_refer_alloc(p)) {
 			transmit_response_reliable(p, "500 Server Internal Error", req);
 			append_history(p, "Xfer", "INVITE/Replace Failed. Out of memory.");
 			sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT);
@@ -26302,7 +26311,7 @@
 	}
 
 	/* Allocate memory for call transfer data */
-	if (!p->refer && !sip_refer_alloc(p)) {
+	if (!sip_refer_alloc(p)) {
 		transmit_response(p, "500 Internal Server Error", req);
 		append_history(p, "Xfer", "Refer failed. Memory allocation error.");
 		res = -3;




More information about the asterisk-commits mailing list