ast_framehook_attach() must be called with the channel locked.
authorRichard Mudgett <rmudgett@digium.com>
Mon, 22 Aug 2016 20:01:37 +0000 (15:01 -0500)
committerRichard Mudgett <rmudgett@digium.com>
Thu, 25 Aug 2016 22:11:50 +0000 (17:11 -0500)
The framehook container could become corrupted if the channel lock is not
held before calling.

Change-Id: I1a6b957a1f7b899eb29a186915f8cccab886a438

main/bridge_basic.c
res/res_pjsip_refer.c
res/res_pjsip_t38.c

index 8d7fbae..6c411fb 100644 (file)
@@ -3088,7 +3088,9 @@ static int attach_framehook(struct attended_transfer_properties *props, struct a
        ao2_ref(props, +1);
        target_interface.data = props;
 
+       ast_channel_lock(channel);
        props->target_framehook_id = ast_framehook_attach(channel, &target_interface);
+       ast_channel_unlock(channel);
        if (props->target_framehook_id == -1) {
                ao2_ref(props, -1);
                return -1;
index 1043a1e..78d6e23 100644 (file)
@@ -607,7 +607,10 @@ static void refer_blind_callback(struct ast_channel *chan, struct transfer_chann
                ao2_ref(refer->progress, +1);
 
                /* If we can't attach a frame hook for whatever reason send a notification of success immediately */
-               if ((refer->progress->framehook = ast_framehook_attach(chan, &hook)) < 0) {
+               ast_channel_lock(chan);
+               refer->progress->framehook = ast_framehook_attach(chan, &hook);
+               ast_channel_unlock(chan);
+               if (refer->progress->framehook < 0) {
                        struct refer_progress_notification *notification = refer_progress_notification_alloc(refer->progress, 200,
                                PJSIP_EVSUB_STATE_TERMINATED);
 
index 76720ac..150336a 100644 (file)
@@ -501,25 +501,27 @@ static void t38_attach_framehook(struct ast_sip_session *session)
                return;
        }
 
-       /* Skip attaching the framehook if the T.38 datastore already exists for the channel */
        ast_channel_lock(session->channel);
-       if ((datastore = ast_channel_datastore_find(session->channel, &t38_framehook_datastore, NULL))) {
+
+       /* Skip attaching the framehook if the T.38 datastore already exists for the channel */
+       datastore = ast_channel_datastore_find(session->channel, &t38_framehook_datastore,
+               NULL);
+       if (datastore) {
                ast_channel_unlock(session->channel);
                return;
        }
-       ast_channel_unlock(session->channel);
 
        framehook_id = ast_framehook_attach(session->channel, &hook);
        if (framehook_id < 0) {
-               ast_log(LOG_WARNING, "Could not attach T.38 Frame hook to channel, T.38 will be unavailable on '%s'\n",
+               ast_log(LOG_WARNING, "Could not attach T.38 Frame hook, T.38 will be unavailable on '%s'\n",
                        ast_channel_name(session->channel));
+               ast_channel_unlock(session->channel);
                return;
        }
 
-       ast_channel_lock(session->channel);
        datastore = ast_datastore_alloc(&t38_framehook_datastore, NULL);
        if (!datastore) {
-               ast_log(LOG_ERROR, "Could not attach T.38 Frame hook to channel, T.38 will be unavailable on '%s'\n",
+               ast_log(LOG_ERROR, "Could not alloc T.38 Frame hook datastore, T.38 will be unavailable on '%s'\n",
                        ast_channel_name(session->channel));
                ast_framehook_detach(session->channel, framehook_id);
                ast_channel_unlock(session->channel);