From: Richard Mudgett Date: Fri, 20 May 2011 16:43:02 +0000 (+0000) Subject: Crash while transferring a call during DTMF feature timeout. X-Git-Tag: 1.8.5-rc1~11^2~95 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=11b3c3add1b503875f67d6d5e314c490c2e595d3;p=thirdparty%2Fasterisk.git Crash while transferring a call during DTMF feature timeout. 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 --- diff --git a/main/channel.c b/main/channel.c index cb1c36e38a..3396baf254 100644 --- a/main/channel.c +++ b/main/channel.c @@ -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) { diff --git a/main/features.c b/main/features.c index eeeac10458..c7f6911089 100644 --- a/main/features.c +++ b/main/features.c @@ -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