From 9479a831f02eb5b4d401bbadc2d1eba60da0bb5c Mon Sep 17 00:00:00 2001 From: Russell Bryant Date: Wed, 5 Mar 2008 22:37:09 +0000 Subject: [PATCH] Fix a potential deadlock and a few different potential crashes. (closes issue #12145, reported by thiagarcia, patched by me) git-svn-id: https://origsvn.digium.com/svn/asterisk/branches/1.4@106237 65c4cc65-6c06-0410-ace0-fbb531ad65f3 --- channels/chan_iax2.c | 39 ++++++++++++++++++++++++++++----------- 1 file changed, 28 insertions(+), 11 deletions(-) diff --git a/channels/chan_iax2.c b/channels/chan_iax2.c index 0f17c80b14..0970633209 100644 --- a/channels/chan_iax2.c +++ b/channels/chan_iax2.c @@ -6412,7 +6412,10 @@ static int timing_read(int *id, int fd, short events, void *cbdata) because by the time they could get tpeerlock, we've already grabbed it */ if (option_debug) ast_log(LOG_DEBUG, "Dropping unused iax2 trunk peer '%s:%d'\n", ast_inet_ntoa(drop->addr.sin_addr), ntohs(drop->addr.sin_port)); - free(drop->trunkdata); + if (drop->trunkdata) { + free(drop->trunkdata); + drop->trunkdata = NULL; + } ast_mutex_unlock(&drop->lock); ast_mutex_destroy(&drop->lock); free(drop); @@ -7564,26 +7567,40 @@ retryowner: iax2_destroy(fr->callno); break; case IAX_COMMAND_TRANSFER: - if (iaxs[fr->callno]->owner && ast_bridged_channel(iaxs[fr->callno]->owner) && ies.called_number) { + { + struct ast_channel *bridged_chan; + + if (iaxs[fr->callno]->owner && (bridged_chan = ast_bridged_channel(iaxs[fr->callno]->owner)) && ies.called_number) { /* Set BLINDTRANSFER channel variables */ - pbx_builtin_setvar_helper(iaxs[fr->callno]->owner, "BLINDTRANSFER", ast_bridged_channel(iaxs[fr->callno]->owner)->name); - pbx_builtin_setvar_helper(ast_bridged_channel(iaxs[fr->callno]->owner), "BLINDTRANSFER", iaxs[fr->callno]->owner->name); + + ast_mutex_unlock(&iaxsl[fr->callno]); + pbx_builtin_setvar_helper(iaxs[fr->callno]->owner, "BLINDTRANSFER", bridged_chan->name); + ast_mutex_lock(&iaxsl[fr->callno]); + if (!iaxs[fr->callno]) { + ast_mutex_unlock(&iaxsl[fr->callno]); + return 1; + } + + pbx_builtin_setvar_helper(bridged_chan, "BLINDTRANSFER", iaxs[fr->callno]->owner->name); if (!strcmp(ies.called_number, ast_parking_ext())) { - if (iax_park(ast_bridged_channel(iaxs[fr->callno]->owner), iaxs[fr->callno]->owner)) { - ast_log(LOG_WARNING, "Failed to park call on '%s'\n", ast_bridged_channel(iaxs[fr->callno]->owner)->name); - } else if (ast_bridged_channel(iaxs[fr->callno]->owner)) - ast_log(LOG_DEBUG, "Parked call on '%s'\n", ast_bridged_channel(iaxs[fr->callno]->owner)->name); + if (iax_park(bridged_chan, iaxs[fr->callno]->owner)) { + ast_log(LOG_WARNING, "Failed to park call on '%s'\n", bridged_chan->name); + } else { + ast_log(LOG_DEBUG, "Parked call on '%s'\n", bridged_chan->name); + } } else { - if (ast_async_goto(ast_bridged_channel(iaxs[fr->callno]->owner), iaxs[fr->callno]->context, ies.called_number, 1)) - ast_log(LOG_WARNING, "Async goto of '%s' to '%s@%s' failed\n", ast_bridged_channel(iaxs[fr->callno]->owner)->name, + if (ast_async_goto(bridged_chan, iaxs[fr->callno]->context, ies.called_number, 1)) + ast_log(LOG_WARNING, "Async goto of '%s' to '%s@%s' failed\n", bridged_chan->name, ies.called_number, iaxs[fr->callno]->context); else - ast_log(LOG_DEBUG, "Async goto of '%s' to '%s@%s' started\n", ast_bridged_channel(iaxs[fr->callno]->owner)->name, + ast_log(LOG_DEBUG, "Async goto of '%s' to '%s@%s' started\n", bridged_chan->name, ies.called_number, iaxs[fr->callno]->context); } } else ast_log(LOG_DEBUG, "Async goto not applicable on call %d\n", fr->callno); + break; + } case IAX_COMMAND_ACCEPT: /* Ignore if call is already up or needs authentication or is a TBD */ if (ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED | IAX_STATE_TBD | IAX_STATE_AUTHENTICATED))