mirror of
				https://github.com/asterisk/asterisk.git
				synced 2025-11-03 20:38:59 +00:00 
			
		
		
		
	bridge_native_rtp.c: Fix native rtp bridge data race.
native_rtp_bridge_compatible() didn't lock the bridge channels before checking the channels for native bridging ability. As a result, one of the channel's native format capabilities structure got replaced out from under the native bridge check. Use of a stale pointer to freed memory causes bad things to happen. MALLOC_DEBUG, DO_CRASH, and the tests/channels/pjsip/transfers/blind_transfer/caller_direct_media testsuite test caught this. * Add missing channel locking in native_rtp_bridge_compatible(). Change-Id: If25fdb3ac8e85563c4857fb8216b3d9dc3d0fa53
This commit is contained in:
		@@ -310,10 +310,8 @@ static int native_rtp_bridge_capable(struct ast_channel *chan)
 | 
			
		||||
	return !ast_channel_has_hook_requiring_audio(chan);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static int native_rtp_bridge_compatible(struct ast_bridge *bridge)
 | 
			
		||||
static int native_rtp_bridge_compatible_check(struct ast_bridge *bridge, struct ast_bridge_channel *bc0, struct ast_bridge_channel *bc1)
 | 
			
		||||
{
 | 
			
		||||
	struct ast_bridge_channel *bc0 = AST_LIST_FIRST(&bridge->channels);
 | 
			
		||||
	struct ast_bridge_channel *bc1 = AST_LIST_LAST(&bridge->channels);
 | 
			
		||||
	enum ast_rtp_glue_result native_type;
 | 
			
		||||
	struct ast_rtp_glue *glue0, *glue1;
 | 
			
		||||
	RAII_VAR(struct ast_rtp_instance *, instance0, NULL, ao2_cleanup);
 | 
			
		||||
@@ -324,13 +322,6 @@ static int native_rtp_bridge_compatible(struct ast_bridge *bridge)
 | 
			
		||||
	RAII_VAR(struct ast_format_cap *, cap1, NULL, ao2_cleanup);
 | 
			
		||||
	int read_ptime0, read_ptime1, write_ptime0, write_ptime1;
 | 
			
		||||
 | 
			
		||||
	/* We require two channels before even considering native bridging */
 | 
			
		||||
	if (bridge->num_channels != 2) {
 | 
			
		||||
		ast_debug(1, "Bridge '%s' can not use native RTP bridge as two channels are required\n",
 | 
			
		||||
			bridge->uniqueid);
 | 
			
		||||
		return 0;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if (!native_rtp_bridge_capable(bc0->chan)) {
 | 
			
		||||
		ast_debug(1, "Bridge '%s' can not use native RTP bridge as channel '%s' has features which prevent it\n",
 | 
			
		||||
			bridge->uniqueid, ast_channel_name(bc0->chan));
 | 
			
		||||
@@ -406,6 +397,30 @@ static int native_rtp_bridge_compatible(struct ast_bridge *bridge)
 | 
			
		||||
	return 1;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static int native_rtp_bridge_compatible(struct ast_bridge *bridge)
 | 
			
		||||
{
 | 
			
		||||
	struct ast_bridge_channel *bc0;
 | 
			
		||||
	struct ast_bridge_channel *bc1;
 | 
			
		||||
	int is_compatible;
 | 
			
		||||
 | 
			
		||||
	/* We require two channels before even considering native bridging */
 | 
			
		||||
	if (bridge->num_channels != 2) {
 | 
			
		||||
		ast_debug(1, "Bridge '%s' can not use native RTP bridge as two channels are required\n",
 | 
			
		||||
			bridge->uniqueid);
 | 
			
		||||
		return 0;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	bc0 = AST_LIST_FIRST(&bridge->channels);
 | 
			
		||||
	bc1 = AST_LIST_LAST(&bridge->channels);
 | 
			
		||||
 | 
			
		||||
	ast_channel_lock_both(bc0->chan, bc1->chan);
 | 
			
		||||
	is_compatible = native_rtp_bridge_compatible_check(bridge, bc0, bc1);
 | 
			
		||||
	ast_channel_unlock(bc0->chan);
 | 
			
		||||
	ast_channel_unlock(bc1->chan);
 | 
			
		||||
 | 
			
		||||
	return is_compatible;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/*! \brief Helper function which adds frame hook to bridge channel */
 | 
			
		||||
static int native_rtp_bridge_framehook_attach(struct ast_bridge_channel *bridge_channel)
 | 
			
		||||
{
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user