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 git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@386289 65c4cc65-6c06-0410-ace0-fbb531ad65f3
This commit is contained in:
parent
e05870ccae
commit
c137d12111
|
@ -7516,8 +7516,11 @@ static enum ast_bridge_result ast_generic_bridge(struct ast_channel *c0, struct
|
||||||
if (ast_channel_softhangup_internal_flag(c1) & AST_SOFTHANGUP_UNBRIDGE) {
|
if (ast_channel_softhangup_internal_flag(c1) & AST_SOFTHANGUP_UNBRIDGE) {
|
||||||
ast_channel_clear_softhangup(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(c0, c1);
|
||||||
ast_channel_internal_bridged_channel_set(c1, c0);
|
ast_channel_internal_bridged_channel_set(c1, c0);
|
||||||
|
ast_channel_unlock(c0);
|
||||||
|
ast_channel_unlock(c1);
|
||||||
}
|
}
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
@ -7799,8 +7802,11 @@ enum ast_bridge_result ast_channel_bridge(struct ast_channel *c0, struct ast_cha
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Keep track of bridge */
|
/* Keep track of bridge */
|
||||||
|
ast_channel_lock_both(c0, c1);
|
||||||
ast_channel_internal_bridged_channel_set(c0, c1);
|
ast_channel_internal_bridged_channel_set(c0, c1);
|
||||||
ast_channel_internal_bridged_channel_set(c1, c0);
|
ast_channel_internal_bridged_channel_set(c1, c0);
|
||||||
|
ast_channel_unlock(c0);
|
||||||
|
ast_channel_unlock(c1);
|
||||||
|
|
||||||
ast_set_owners_and_peers(c0, c1);
|
ast_set_owners_and_peers(c0, c1);
|
||||||
|
|
||||||
|
@ -7896,8 +7902,11 @@ enum ast_bridge_result ast_channel_bridge(struct ast_channel *c0, struct ast_cha
|
||||||
if (ast_channel_softhangup_internal_flag(c1) & AST_SOFTHANGUP_UNBRIDGE) {
|
if (ast_channel_softhangup_internal_flag(c1) & AST_SOFTHANGUP_UNBRIDGE) {
|
||||||
ast_channel_clear_softhangup(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(c0, c1);
|
||||||
ast_channel_internal_bridged_channel_set(c1, c0);
|
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 */
|
/* Stop if we're a zombie or need a soft hangup */
|
||||||
|
@ -7990,8 +7999,11 @@ enum ast_bridge_result ast_channel_bridge(struct ast_channel *c0, struct ast_cha
|
||||||
ast_indicate(c0, AST_CONTROL_SRCUPDATE);
|
ast_indicate(c0, AST_CONTROL_SRCUPDATE);
|
||||||
ast_indicate(c1, 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(c0, NULL);
|
||||||
ast_channel_internal_bridged_channel_set(c1, NULL);
|
ast_channel_internal_bridged_channel_set(c1, NULL);
|
||||||
|
ast_channel_unlock(c0);
|
||||||
|
ast_channel_unlock(c1);
|
||||||
|
|
||||||
manager_bridge_event(0, 1, c0, 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));
|
ast_debug(1, "Bridge stops bridging channels %s and %s\n", ast_channel_name(c0), ast_channel_name(c1));
|
||||||
|
|
Loading…
Reference in New Issue