summaryrefslogtreecommitdiff
path: root/res/snmp
diff options
context:
space:
mode:
authorRichard Mudgett <rmudgett@digium.com>2015-01-20 16:59:30 +0000
committerRichard Mudgett <rmudgett@digium.com>2015-01-20 16:59:30 +0000
commite4738a59eb7c3b55b096902967cea31e8f842057 (patch)
tree931d3d3f9292a7cc38bc5245c16d94e13178e215 /res/snmp
parent14b8e03dad718a638f50f9de928b85951cb1e0bc (diff)
CHANNEL(peer), chan_iax2, res_fax, SNMP agent: Fix deadlock from reaching across a bridge.
Calling ast_channel_bridge_peer() cannot be done while holding any channel locks. The reported issue hit the deadlock in chan_iax2, but an audit of the ast_channel_bridge_peer() calls found three more locations where the same deadlock can occur. * Made CHANNEL(peer), res_fax, and the SNMP agent not call ast_channel_bridge_peer() with any channel locked. For CHANNEL(peer) I had to rework the logic to not hold the channel lock. * Made chan_iax2 no longer call ast_channel_bridge_peer(). It was done for legacy reasons that no longer apply. * Removed the iax.conf forcejitterbuffer option. It is now always enabled when the jitterbuffer option is enabled. If you put a jitter buffer on a channel it will be on the channel. ASTERISK-24600 #close Reported by: Jeff Collell Review: https://reviewboard.asterisk.org/r/4342/ ........ Merged revisions 430817 from http://svn.asterisk.org/svn/asterisk/branches/13 git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@430819 65c4cc65-6c06-0410-ace0-fbb531ad65f3
Diffstat (limited to 'res/snmp')
-rw-r--r--res/snmp/agent.c10
1 files changed, 8 insertions, 2 deletions
diff --git a/res/snmp/agent.c b/res/snmp/agent.c
index abaf37224..9d1528dde 100644
--- a/res/snmp/agent.c
+++ b/res/snmp/agent.c
@@ -298,12 +298,18 @@ static u_char *ast_var_channels_table(struct variable *vp, oid *name, size_t *le
}
break;
case ASTCHANBRIDGE:
- if ((bridge = ast_channel_bridge_peer(chan)) != NULL) {
+ ast_channel_unlock(chan);
+ bridge = ast_channel_bridge_peer(chan);
+ if (bridge) {
+ ast_channel_lock(bridge);
ast_copy_string(string_ret, ast_channel_name(bridge), sizeof(string_ret));
+ ast_channel_unlock(bridge);
+ ast_channel_unref(bridge);
+
*var_len = strlen(string_ret);
ret = (u_char *)string_ret;
- ast_channel_unref(bridge);
}
+ ast_channel_lock(chan);
break;
case ASTCHANMASQ:
if (ast_channel_masq(chan) && !ast_strlen_zero(ast_channel_name(ast_channel_masq(chan)))) {