[svn-commits] rmudgett: branch 1.8 r378092 - /branches/1.8/main/loader.c

SVN commits to the Digium repositories svn-commits at lists.digium.com
Mon Dec 17 17:07:29 CST 2012


Author: rmudgett
Date: Mon Dec 17 17:07:24 2012
New Revision: 378092

URL: http://svnview.digium.com/svn/asterisk?view=rev&rev=378092
Log:
Fix potential double free when unloading a module.

Modified:
    branches/1.8/main/loader.c

Modified: branches/1.8/main/loader.c
URL: http://svnview.digium.com/svn/asterisk/branches/1.8/main/loader.c?view=diff&rev=378092&r1=378091&r2=378092
==============================================================================
--- branches/1.8/main/loader.c (original)
+++ branches/1.8/main/loader.c Mon Dec 17 17:07:24 2012
@@ -233,9 +233,18 @@
 	if (!u) {
 		return;
 	}
+
 	AST_LIST_LOCK(&mod->users);
-	AST_LIST_REMOVE(&mod->users, u, entry);
+	u = AST_LIST_REMOVE(&mod->users, u, entry);
 	AST_LIST_UNLOCK(&mod->users);
+	if (!u) {
+		/*
+		 * Was not in the list.  Either a bad pointer or
+		 * __ast_module_user_hangup_all() has been called.
+		 */
+		return;
+	}
+
 	ast_atomic_fetchadd_int(&mod->usecount, -1);
 	ast_free(u);
 
@@ -554,15 +563,26 @@
 	}
 
 	if (!error) {
+		/* Request any channels attached to the module to hangup. */
 		__ast_module_user_hangup_all(mod);
+
 		res = mod->info->unload();
-
 		if (res) {
 			ast_log(LOG_WARNING, "Firm unload failed for %s\n", resource_name);
-			if (force <= AST_FORCE_FIRM)
+			if (force <= AST_FORCE_FIRM) {
 				error = 1;
-			else
+			} else {
 				ast_log(LOG_WARNING, "** Dangerous **: Unloading resource anyway, at user request\n");
+			}
+		}
+
+		if (!error) {
+			/*
+			 * Request hangup on any channels that managed to get attached
+			 * while we called the module unload function.
+			 */
+			__ast_module_user_hangup_all(mod);
+			sched_yield();
 		}
 	}
 




More information about the svn-commits mailing list