]> git.ipfire.org Git - thirdparty/asterisk.git/commitdiff
Merged revisions 114112 via svnmerge from
authorMark Michelson <mmichelson@digium.com>
Mon, 14 Apr 2008 16:25:09 +0000 (16:25 +0000)
committerMark Michelson <mmichelson@digium.com>
Mon, 14 Apr 2008 16:25:09 +0000 (16:25 +0000)
https://origsvn.digium.com/svn/asterisk/branches/1.4

........
r114112 | mmichelson | 2008-04-14 11:24:22 -0500 (Mon, 14 Apr 2008) | 9 lines

If the datastore has been moved to another channel due to a masquerade, then
freeing the datastore here causes an eventual double free when the new channel
hangs up. We should only free the datastore if we were able to successfully remove
it from the channel we are referencing (i.e. the datastore was not moved).

(closes issue #12359)
Reported by: pguido

........

git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@114113 65c4cc65-6c06-0410-ace0-fbb531ad65f3

apps/app_dial.c
apps/app_queue.c

index 9c2664aa6b7a01eedd60ed98cab0097b99bc88ca..6d0c6a6e7f0ca3a45257b4e9ec7145108486f6dc 100644 (file)
@@ -1600,8 +1600,14 @@ static int dial_exec_full(struct ast_channel *chan, void *data, struct ast_flags
        time(&start_time);
        peer = wait_for_answer(chan, outgoing, &to, peerflags, &pa, &num, &result);
 
-       ast_channel_datastore_remove(chan, datastore);
-       ast_channel_datastore_free(datastore);
+       /* The ast_channel_datastore_remove() function could fail here if the
+        * datastore was moved to another channel during a masquerade. If this is
+        * the case, don't free the datastore here because later, when the channel
+        * to which the datastore was moved hangs up, it will attempt to free this
+        * datastore again, causing a crash
+        */
+       if (!ast_channel_datastore_remove(chan, datastore))
+               ast_channel_datastore_free(datastore);
        if (!peer) {
                if (result) {
                        res = result;
index 7f01445df55373c16b7fe78e61e5932ac62fd815..aef06aa2d6f3997d962715cc72199e45eb919ed4 100644 (file)
@@ -3252,8 +3252,13 @@ static int try_calling(struct queue_ent *qe, const char *options, char *announce
        if (use_weight)
                ao2_unlock(queues);
        lpeer = wait_for_answer(qe, outgoing, &to, &digit, numbusies, ast_test_flag(&(bridge_config.features_caller), AST_FEATURE_DISCONNECT), forwardsallowed);
-       if (datastore) {
-               ast_channel_datastore_remove(qe->chan, datastore);
+       /* The ast_channel_datastore_remove() function could fail here if the
+        * datastore was moved to another channel during a masquerade. If this is
+        * the case, don't free the datastore here because later, when the channel
+        * to which the datastore was moved hangs up, it will attempt to free this
+        * datastore again, causing a crash
+        */
+       if (datastore && !ast_channel_datastore_remove(qe->chan, datastore)) {
                ast_channel_datastore_free(datastore);
        }
        ao2_lock(qe->parent);