diff --git a/apps/app_dial.c b/apps/app_dial.c index 2d5bf09382..e9189b4bf6 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; diff --git a/apps/app_queue.c b/apps/app_queue.c index 36ba8e2131..d35ece846a 100644 --- a/apps/app_queue.c +++ b/apps/app_queue.c @@ -2753,8 +2753,13 @@ static int try_calling(struct queue_ent *qe, const char *options, char *announce if (use_weight) AST_LIST_UNLOCK(&queues); lpeer = wait_for_answer(qe, outgoing, &to, &digit, numbusies, ast_test_flag(&(bridge_config.features_caller), AST_FEATURE_DISCONNECT), forwardsallowed); - if (datastore) { - ast_channel_datastore_remove(qe->chan, 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 (datastore && !ast_channel_datastore_remove(qe->chan, datastore)) { ast_channel_datastore_free(datastore); } ast_mutex_lock(&qe->parent->lock);