[asterisk-commits] rmudgett: branch 11 r386286 - in /branches/11: ./ main/channel.c

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


Author: rmudgett
Date: Mon Apr 22 11:30:53 2013
New Revision: 386286

URL: http://svnview.digium.com/svn/asterisk?view=rev&rev=386286
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

Modified:
    branches/11/   (props changed)
    branches/11/main/channel.c

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

Modified: branches/11/main/channel.c
URL: http://svnview.digium.com/svn/asterisk/branches/11/main/channel.c?view=diff&rev=386286&r1=386285&r2=386286
==============================================================================
--- branches/11/main/channel.c (original)
+++ branches/11/main/channel.c Mon Apr 22 11:30:53 2013
@@ -7549,8 +7549,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;
 		}
@@ -7831,8 +7834,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);
 
@@ -7926,8 +7932,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);
 			ast_debug(1, "Unbridge signal received. Ending native bridge.\n");
 			continue;
 		}
@@ -7973,8 +7982,11 @@
 					continue;
 				}
 
+				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);
 				ast_format_cap_destroy(o0nativeformats);
 				ast_format_cap_destroy(o1nativeformats);
 				return res;
@@ -8031,8 +8043,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