mirror of
				https://github.com/asterisk/asterisk.git
				synced 2025-11-04 05:15:22 +00:00 
			
		
		
		
	func_lock: Fix memory corruption during unload.
AST_TRAVERSE accessess current as current = current->(field).next ... and since we free current (and ast_free poisons the memory) we either end up on a ast_mutex_lock to a non-existing lock that can never be obtained, or a segfault. Incidentally add logging in the "we have to wait for a lock to release" case, and remove an ineffective statement that sets memory that was just cleared by ast_calloc to zero. Change-Id: Id19ba3d9867b23d0e6783b97e6ecd8e62698b8c3 Signed-off-by: Jaco Kroon <jaco@uls.co.za>
This commit is contained in:
		
				
					committed by
					
						
						Friendly Automation
					
				
			
			
				
	
			
			
			
						parent
						
							caceba7988
						
					
				
				
					commit
					e8875d5ca1
				
			@@ -249,7 +249,6 @@ static int get_lock(struct ast_channel *chan, char *lockname, int trylock)
 | 
			
		||||
			AST_LIST_UNLOCK(&locklist);
 | 
			
		||||
			return -1;
 | 
			
		||||
		}
 | 
			
		||||
		current->requesters = 0;
 | 
			
		||||
		AST_LIST_INSERT_TAIL(&locklist, current, entries);
 | 
			
		||||
	}
 | 
			
		||||
	/* Add to requester list */
 | 
			
		||||
@@ -449,9 +448,16 @@ static int unload_module(void)
 | 
			
		||||
	ast_custom_function_unregister(&trylock_function);
 | 
			
		||||
 | 
			
		||||
	AST_LIST_LOCK(&locklist);
 | 
			
		||||
	AST_LIST_TRAVERSE(&locklist, current, entries) {
 | 
			
		||||
	while ((current = AST_LIST_REMOVE_HEAD(&locklist, entries))) {
 | 
			
		||||
		int warned = 0;
 | 
			
		||||
		ast_mutex_lock(¤t->mutex);
 | 
			
		||||
		while (current->owner || current->requesters) {
 | 
			
		||||
			if (!warned) {
 | 
			
		||||
				ast_log(LOG_WARNING, "Waiting for %d requesters for %s lock %s.\n",
 | 
			
		||||
						current->requesters, current->owner ? "locked" : "unlocked",
 | 
			
		||||
						current->name);
 | 
			
		||||
				warned = 1;
 | 
			
		||||
			}
 | 
			
		||||
			/* either the mutex is locked, or other parties are currently in get_lock,
 | 
			
		||||
			 * we need to wait for all of those to clear first */
 | 
			
		||||
			ast_cond_wait(¤t->cond, ¤t->mutex);
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user