aboutsummaryrefslogtreecommitdiffstats
path: root/apps/app_dial.c
diff options
context:
space:
mode:
authormmichelson <mmichelson@f38db490-d61c-443f-a65b-d21fe96a405b>2008-04-14 16:24:22 +0000
committermmichelson <mmichelson@f38db490-d61c-443f-a65b-d21fe96a405b>2008-04-14 16:24:22 +0000
commitb36371262c8b3b6b81c490cce5a0c6a269a3b9de (patch)
tree088ee0c5ba6ccf6ca7c15b77d192070239990825 /apps/app_dial.c
parentade38fc06cbeb9b0544c701c8bdca21fda7e39fe (diff)
If the datastore has been moved to another channel due to a masquerade, then
freeing the datastore here causes an eventual double free when the new channel hangs up. We should only free the datastore if we were able to successfully remove it from the channel we are referencing (i.e. the datastore was not moved). (closes issue #12359) Reported by: pguido git-svn-id: http://svn.digium.com/svn/asterisk/branches/1.4@114112 f38db490-d61c-443f-a65b-d21fe96a405b
Diffstat (limited to 'apps/app_dial.c')
-rw-r--r--apps/app_dial.c10
1 files changed, 8 insertions, 2 deletions
diff --git a/apps/app_dial.c b/apps/app_dial.c
index 2d5bf0938..e9189b4bf 100644
--- a/apps/app_dial.c
+++ b/apps/app_dial.c
@@ -1320,8 +1320,14 @@ static int dial_exec_full(struct ast_channel *chan, void *data, struct ast_flags
time(&start_time);
peer = wait_for_answer(chan, outgoing, &to, peerflags, &sentringing, status, sizeof(status), numbusy, numnochan, numcongestion, ast_test_flag(&opts, OPT_PRIORITY_JUMP), &result);
- ast_channel_datastore_remove(chan, datastore);
- ast_channel_datastore_free(datastore);
+ /* The ast_channel_datastore_remove() function could fail here if the
+ * datastore was moved to another channel during a masquerade. If this is
+ * the case, don't free the datastore here because later, when the channel
+ * to which the datastore was moved hangs up, it will attempt to free this
+ * datastore again, causing a crash
+ */
+ if (!ast_channel_datastore_remove(chan, datastore))
+ ast_channel_datastore_free(datastore);
if (!peer) {
if (result) {
res = result;