[asterisk-commits] rmudgett: trunk r386289 - in /trunk: ./ main/channel.c

SVN commits to the Asterisk project asterisk-commits at lists.digium.com
Mon Apr 22 11:44:25 CDT 2013


Author: rmudgett
Date: Mon Apr 22 11:44:21 2013
New Revision: 386289

URL: http://svnview.digium.com/svn/asterisk?view=rev&rev=386289
Log:
Fix crash when AMI redirect action redirects two channels out of a bridge.

The two party bridging loops were changing the bridge peer pointers
without the channel locks held.  Thus when ast_channel_massquerade()
tested and used the pointer there is a small window of opportunity for the
pointers to become NULL even though the masquerade code has the channels
locked.

(closes issue ASTERISK-21356)
Reported by: William luke
Patches:
      jira_asterisk_21356_v11.patch (license #5621) patch uploaded by rmudgett
Tested by: William luke
........

Merged revisions 386256 from http://svn.asterisk.org/svn/asterisk/branches/1.8
........

Merged revisions 386286 from http://svn.asterisk.org/svn/asterisk/branches/11

Modified:
    trunk/   (props changed)
    trunk/main/channel.c

Propchange: trunk/
------------------------------------------------------------------------------
Binary property 'branch-11-merged' - no diff available.

Modified: trunk/main/channel.c
URL: http://svnview.digium.com/svn/asterisk/trunk/main/channel.c?view=diff&rev=386289&r1=386288&r2=386289
==============================================================================
--- trunk/main/channel.c (original)
+++ trunk/main/channel.c Mon Apr 22 11:44:21 2013
@@ -7516,8 +7516,11 @@
 				if (ast_channel_softhangup_internal_flag(c1) & AST_SOFTHANGUP_UNBRIDGE) {
 					ast_channel_clear_softhangup(c1, AST_SOFTHANGUP_UNBRIDGE);
 				}
+				ast_channel_lock_both(c0, c1);
 				ast_channel_internal_bridged_channel_set(c0, c1);
 				ast_channel_internal_bridged_channel_set(c1, c0);
+				ast_channel_unlock(c0);
+				ast_channel_unlock(c1);
 			}
 			continue;
 		}
@@ -7799,8 +7802,11 @@
 	}
 
 	/* Keep track of bridge */
+	ast_channel_lock_both(c0, c1);
 	ast_channel_internal_bridged_channel_set(c0, c1);
 	ast_channel_internal_bridged_channel_set(c1, c0);
+	ast_channel_unlock(c0);
+	ast_channel_unlock(c1);
 
 	ast_set_owners_and_peers(c0, c1);
 
@@ -7896,8 +7902,11 @@
 			if (ast_channel_softhangup_internal_flag(c1) & AST_SOFTHANGUP_UNBRIDGE) {
 				ast_channel_clear_softhangup(c1, AST_SOFTHANGUP_UNBRIDGE);
 			}
+			ast_channel_lock_both(c0, c1);
 			ast_channel_internal_bridged_channel_set(c0, c1);
 			ast_channel_internal_bridged_channel_set(c1, c0);
+			ast_channel_unlock(c0);
+			ast_channel_unlock(c1);
 		}
 
 		/* Stop if we're a zombie or need a soft hangup */
@@ -7990,8 +7999,11 @@
 	ast_indicate(c0, AST_CONTROL_SRCUPDATE);
 	ast_indicate(c1, AST_CONTROL_SRCUPDATE);
 
+	ast_channel_lock_both(c0, c1);
 	ast_channel_internal_bridged_channel_set(c0, NULL);
 	ast_channel_internal_bridged_channel_set(c1, NULL);
+	ast_channel_unlock(c0);
+	ast_channel_unlock(c1);
 
 	manager_bridge_event(0, 1, c0, c1);
 	ast_debug(1, "Bridge stops bridging channels %s and %s\n", ast_channel_name(c0), ast_channel_name(c1));




More information about the asterisk-commits mailing list