From 3841520a6e4f910c4c44130204b6cc7f4eadf76a Mon Sep 17 00:00:00 2001 From: Matthew Jordan Date: Mon, 1 Jul 2013 21:24:20 +0000 Subject: Prevent crash during synchronous AMI origination by ref bumping returned channel The originate APIs allow callers to provide a pointer to a channel that will point to the originated channel if the function call succeeds. This is used by AMI to provide channel information when the originate is performed synchronously. Unfortunately, if the originate fails in certain ways, the outbound channel is already disposed of during the dialing itself. This results in the channel being improperly dereferenced by the internal originate function in pbx.c. This patch ref bumps the channel to prevent this from occurring. Callers must now unlock and unref the channel (which is more in line with general channel management guidelines anyway). This only affects manager, as it is the only consumer of this API function that actually passes in a channel pointer. Review: https://reviewboard.asterisk.org/r/2617/ git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@393361 65c4cc65-6c06-0410-ace0-fbb531ad65f3 --- main/manager.c | 3 ++- main/pbx.c | 2 ++ 2 files changed, 4 insertions(+), 1 deletion(-) (limited to 'main') diff --git a/main/manager.c b/main/manager.c index 7e5b1080c..ec031303b 100644 --- a/main/manager.c +++ b/main/manager.c @@ -4329,9 +4329,10 @@ static void *fast_originate(void *data) S_OR(in->cid_name, "") ); - /* Locked by ast_pbx_outgoing_exten or ast_pbx_outgoing_app */ + /* Locked and ref'd by ast_pbx_outgoing_exten or ast_pbx_outgoing_app */ if (chan) { ast_channel_unlock(chan); + ast_channel_unref(chan); } destroy_fast_originate_helper(in); return NULL; diff --git a/main/pbx.c b/main/pbx.c index db737327f..8079edc62 100644 --- a/main/pbx.c +++ b/main/pbx.c @@ -9967,6 +9967,7 @@ static int pbx_outgoing_attempt(const char *type, struct ast_format_cap *cap, co if (channel) { *channel = dialed; + ast_channel_ref(*channel); ast_channel_lock(*channel); } @@ -9981,6 +9982,7 @@ static int pbx_outgoing_attempt(const char *type, struct ast_format_cap *cap, co ast_log(LOG_WARNING, "Unable to spawn dialing thread for '%s/%s'\n", type, addr); if (channel) { ast_channel_unlock(*channel); + ast_channel_unref(*channel); } ao2_ref(outgoing, -1); return -1; -- cgit v1.2.3