]> git.ipfire.org Git - thirdparty/asterisk.git/commitdiff
Crash while transferring a call during DTMF feature timeout.
authorRichard Mudgett <rmudgett@digium.com>
Fri, 20 May 2011 16:43:02 +0000 (16:43 +0000)
committerRichard Mudgett <rmudgett@digium.com>
Fri, 20 May 2011 16:43:02 +0000 (16:43 +0000)
When a call is being attended transferred during the time between
AST_FRAME_DTMF_BEGIN and AST_FRAME_DTMF_END, the transferred channel
becomes a zombie (so tech data is not available), making ast_dtmf_stream()
segfault when it tries to send the DTMF digit (at least with SIP
channels).

Patch based on feature-end-zombie.patch uploaded by Irontec (license 1256)

* Check for zombies when ast_channel_bridge() returns.

* Guarantee that the fo parameter value is initialized in
ast_channel_bridge() before any returns.

(closes issue #19116)
Reported by: Irontec
Tested by: rmudgett

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

main/channel.c
main/features.c

index cb1c36e38a9f9053a23931ef263510eec0e08c0f..3396baf25446517f0595a7fa7dcb89554e42ca02 100644 (file)
@@ -7063,6 +7063,8 @@ enum ast_bridge_result ast_channel_bridge(struct ast_channel *c0, struct ast_cha
        char caller_warning = 0;
        char callee_warning = 0;
 
+       *fo = NULL;
+
        if (c0->_bridge) {
                ast_log(LOG_WARNING, "%s is already in a bridge with %s\n",
                        c0->name, c0->_bridge->name);
@@ -7079,8 +7081,6 @@ enum ast_bridge_result ast_channel_bridge(struct ast_channel *c0, struct ast_cha
            ast_test_flag(c1, AST_FLAG_ZOMBIE) || ast_check_hangup_locked(c1))
                return -1;
 
-       *fo = NULL;
-
        if (ast_tvzero(config->start_time)) {
                config->start_time = ast_tvnow();
                if (config->start_sound) {
index eeeac104582c41d35c6ef24acf2d383852139165..c7f6911089365e49041323d0ca62c7cffcad4b88 100644 (file)
@@ -3628,7 +3628,17 @@ int ast_bridge_call(struct ast_channel *chan,struct ast_channel *peer,struct ast
                struct ast_channel *other;      /* used later */
        
                res = ast_channel_bridge(chan, peer, config, &f, &who);
-               
+
+               if (ast_test_flag(chan, AST_FLAG_ZOMBIE)
+                       || ast_test_flag(peer, AST_FLAG_ZOMBIE)) {
+                       /* Zombies are present time to leave! */
+                       res = -1;
+                       if (f) {
+                               ast_frfree(f);
+                       }
+                       goto before_you_go;
+               }
+
                /* When frame is not set, we are probably involved in a situation
                   where we've timed out.
                   When frame is set, we'll come this code twice; once for DTMF_BEGIN