summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRichard Mudgett <rmudgett@digium.com>2017-12-27 22:36:58 -0600
committerRichard Mudgett <rmudgett@digium.com>2017-12-27 23:16:21 -0600
commit9f1cfbafcadbbcead3cedf9fc51263e95b234f17 (patch)
treeea296e9f8dc2e66a6ccdd40d97fd1787635a4e07
parent92fb393cab7fbd164e299601e94909ba95a0116b (diff)
bridge_native_rtp.c: Fix reentrancy framehook crash.
If two channels enter different native rtp bridges at the same time it is possible that the framehook interface data pointer can be corrupted because the struct variable was declared static. * Fixed the reentrancy corruption by changing the framehook interface struct static variable to a stack local variable. * Moved the hook.data assignment outside of the channel lock. It did not need the lock's protection. It probably was giving a false sense of security. The testsuite channels/pjsip/basic_calls/two_parties/nominal/alice_initiated/bob_hangs_up test caught this with MALLOC_DEBUG and DO_CRASH enabled. Change-Id: If9e35b97d19209b0f984941c1d8eb5f7c55eea91
-rw-r--r--bridges/bridge_native_rtp.c5
1 files changed, 3 insertions, 2 deletions
diff --git a/bridges/bridge_native_rtp.c b/bridges/bridge_native_rtp.c
index 122c132d6..d490183ff 100644
--- a/bridges/bridge_native_rtp.c
+++ b/bridges/bridge_native_rtp.c
@@ -755,7 +755,7 @@ static int native_rtp_bridge_compatible(struct ast_bridge *bridge)
static int native_rtp_bridge_framehook_attach(struct ast_bridge_channel *bridge_channel)
{
struct native_rtp_bridge_channel_data *data = bridge_channel->tech_pvt;
- static struct ast_framehook_interface hook = {
+ struct ast_framehook_interface hook = {
.version = AST_FRAMEHOOK_INTERFACE_VERSION,
.event_cb = native_rtp_framehook,
.destroy_cb = __ao2_cleanup,
@@ -773,9 +773,10 @@ static int native_rtp_bridge_framehook_attach(struct ast_bridge_channel *bridge_
ast_debug(2, "Bridge '%s'. Attaching hook data %p to '%s'\n",
bridge_channel->bridge->uniqueid, data, ast_channel_name(bridge_channel->chan));
- ast_channel_lock(bridge_channel->chan);
/* We're giving 1 ref to the framehook and keeping the one from the alloc for ourselves */
hook.data = ao2_bump(data->hook_data);
+
+ ast_channel_lock(bridge_channel->chan);
data->hook_data->id = ast_framehook_attach(bridge_channel->chan, &hook);
ast_channel_unlock(bridge_channel->chan);
if (data->hook_data->id < 0) {