[asterisk-commits] rmudgett: branch 1.8 r386256 - /branches/1.8/main/channel.c

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


Author: rmudgett
Date: Mon Apr 22 11:10:29 2013
New Revision: 386256

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

Modified:
    branches/1.8/main/channel.c

Modified: branches/1.8/main/channel.c
URL: http://svnview.digium.com/svn/asterisk/branches/1.8/main/channel.c?view=diff&rev=386256&r1=386255&r2=386256
==============================================================================
--- branches/1.8/main/channel.c (original)
+++ branches/1.8/main/channel.c Mon Apr 22 11:10:29 2013
@@ -7223,8 +7223,11 @@
 				if (c1->_softhangup & AST_SOFTHANGUP_UNBRIDGE) {
 					ast_channel_clear_softhangup(c1, AST_SOFTHANGUP_UNBRIDGE);
 				}
+				ast_channel_lock_both(c0, c1);
 				c0->_bridge = c1;
 				c1->_bridge = c0;
+				ast_channel_unlock(c0);
+				ast_channel_unlock(c1);
 			}
 			continue;
 		}
@@ -7471,8 +7474,11 @@
 	}
 
 	/* Keep track of bridge */
+	ast_channel_lock_both(c0, c1);
 	c0->_bridge = c1;
 	c1->_bridge = c0;
+	ast_channel_unlock(c0);
+	ast_channel_unlock(c1);
 
 	ast_set_owners_and_peers(c0, c1);
 
@@ -7569,8 +7575,11 @@
 			if (c1->_softhangup & AST_SOFTHANGUP_UNBRIDGE) {
 				ast_channel_clear_softhangup(c1, AST_SOFTHANGUP_UNBRIDGE);
 			}
+			ast_channel_lock_both(c0, c1);
 			c0->_bridge = c1;
 			c1->_bridge = c0;
+			ast_channel_unlock(c0);
+			ast_channel_unlock(c1);
 			ast_debug(1, "Unbridge signal received. Ending native bridge.\n");
 			continue;
 		}
@@ -7627,8 +7636,11 @@
 					continue;
 				}
 
+				ast_channel_lock_both(c0, c1);
 				c0->_bridge = NULL;
 				c1->_bridge = NULL;
+				ast_channel_unlock(c0);
+				ast_channel_unlock(c1);
 				return res;
 			} else {
 				ast_clear_flag(c0, AST_FLAG_NBRIDGE);
@@ -7678,8 +7690,11 @@
 	ast_indicate(c0, AST_CONTROL_SRCUPDATE);
 	ast_indicate(c1, AST_CONTROL_SRCUPDATE);
 
+	ast_channel_lock_both(c0, c1);
 	c0->_bridge = NULL;
 	c1->_bridge = NULL;
+	ast_channel_unlock(c0);
+	ast_channel_unlock(c1);
 
 	ast_manager_event_multichan(EVENT_FLAG_CALL, "Unlink", 2, chans,
 		"Channel1: %s\r\n"




More information about the asterisk-commits mailing list