[asterisk-commits] file: branch 11 r427709 - /branches/11/main/pbx.c

SVN commits to the Asterisk project asterisk-commits at lists.digium.com
Wed Nov 12 10:10:53 CST 2014


Author: file
Date: Wed Nov 12 10:10:46 2014
New Revision: 427709

URL: http://svnview.digium.com/svn/asterisk?view=rev&rev=427709
Log:
pbx: Fix off-nominal case where a freed extension may still be used.

If during the operation of adding an extension a priority is added but
fails it is possible for the extension to be freed but still exist in
the PBX core. If this occurs subsequent lookups may try to access the
extension and end up in freed memory.

This change removes the extension from the PBX core when the priority
addition fails and then frees the extension.

ASTERISK-24444 #close
Reported by: Leandro Dardini

Review: https://reviewboard.asterisk.org/r/4162/

Modified:
    branches/11/main/pbx.c

Modified: branches/11/main/pbx.c
URL: http://svnview.digium.com/svn/asterisk/branches/11/main/pbx.c?view=diff&rev=427709&r1=427708&r2=427709
==============================================================================
--- branches/11/main/pbx.c (original)
+++ branches/11/main/pbx.c Wed Nov 12 10:10:46 2014
@@ -9903,13 +9903,7 @@
 					"Unable to register extension '%s' priority %d in '%s', already in use\n",
 					tmp->exten, tmp->priority, con->name);
 			}
-			if (tmp->datad) {
-				tmp->datad(tmp->data);
-				/* if you free this, null it out */
-				tmp->data = NULL;
-			}
-
-			ast_free(tmp);
+
 			return -1;
 		}
 		/* we are replacing e, so copy the link fields and then update
@@ -10183,6 +10177,26 @@
 	}
 	if (e && res == 0) { /* exact match, insert in the priority chain */
 		res = add_priority(con, tmp, el, e, replace);
+		if (res < 0) {
+			if (con->pattern_tree) {
+				struct match_char *x = add_exten_to_pattern_tree(con, tmp, 1);
+
+				if (x->exten) {
+					x->deleted = 1;
+					x->exten = 0;
+				}
+
+				ast_hashtab_remove_this_object(con->root_table, tmp);
+			}
+
+			if (tmp->datad) {
+				tmp->datad(tmp->data);
+				/* if you free this, null it out */
+				tmp->data = NULL;
+			}
+
+			ast_free(tmp);
+		}
 		if (lock_context) {
 			ast_unlock_context(con);
 		}




More information about the asterisk-commits mailing list