From 225fd1003fa3016e4a8030cbcaa5b5d0d99a7f45 Mon Sep 17 00:00:00 2001
From: Matt Jordan <mjordan@digium.com>
Date: Thu, 11 Aug 2016 11:13:07 -0500
Subject: [PATCH] app_queue: Prevent crash when a call is forwarded to an
 invalid location

When a call forward attempt is made from a Queue member, the current
code will hang up the forwarding channel in an off-nominal condition
prior to raising the Stasis events informing the rest of Asterisk that
the call was forwarded. This will result in a slew of dreaded FRACKs,
most likely leading to a crash.

This patch modifies the code such that we don't hang up the forwarding
channel even in an off-nominal condition until we've safely raised the
Stasis messages.

ASTERISK-25797 #close

Change-Id: Ife5abed351691fd79105321636eaa8ea8dcdba38
---
 apps/app_queue.c | 13 ++++++++++---
 1 file changed, 10 insertions(+), 3 deletions(-)

diff --git a/apps/app_queue.c b/apps/app_queue.c
index 39413f9a60..a5cb126402 100644
--- a/apps/app_queue.c
+++ b/apps/app_queue.c
@@ -4865,6 +4865,7 @@ static struct callattempt *wait_for_answer(struct queue_ent *qe, struct callatte
 					char tmpchan[256];
 					char *stuff;
 					char *tech;
+					int failed = 0;
 
 					ast_copy_string(tmpchan, ast_channel_call_forward(o->chan), sizeof(tmpchan));
 					ast_copy_string(forwarder, ast_channel_name(o->chan), sizeof(forwarder));
@@ -4977,14 +4978,20 @@ static struct callattempt *wait_for_answer(struct queue_ent *qe, struct callatte
 						if (ast_call(o->chan, stuff, 0)) {
 							ast_log(LOG_NOTICE, "Forwarding failed to dial '%s/%s'\n",
 								tech, stuff);
-							do_hang(o);
-							numnochan++;
+							failed = 1;
 						}
 					}
 
-					ast_channel_publish_dial(qe->chan, o->chan, stuff, NULL);
 					ast_channel_publish_dial_forward(qe->chan, original, o->chan, NULL,
 						"CANCEL", ast_channel_call_forward(original));
+					if (o->chan) {
+						ast_channel_publish_dial(qe->chan, o->chan, stuff, NULL);
+					}
+
+					if (failed) {
+						do_hang(o);
+						numnochan++;
+					}
 
 					/* Hangup the original channel now, in case we needed it */
 					ast_hangup(winner);
-- 
GitLab