]> git.ipfire.org Git - thirdparty/asterisk.git/commitdiff
bridge_native_rtp.c: Fix reentrancy framehook crash.
authorRichard Mudgett <rmudgett@digium.com>
Thu, 28 Dec 2017 04:36:58 +0000 (22:36 -0600)
committerRichard Mudgett <rmudgett@digium.com>
Thu, 28 Dec 2017 05:16:21 +0000 (23:16 -0600)
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

bridges/bridge_native_rtp.c

index 122c132d67cdc2799aa25039d25fed14db10cfaf..d490183ff0534f19b50e30599cf6180ba931df6b 100644 (file)
@@ -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) {