diff --git a/apps/app_dial.c b/apps/app_dial.c index 95757e38b9..c7d4f425a7 100644 --- a/apps/app_dial.c +++ b/apps/app_dial.c @@ -1590,8 +1590,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, &pa, &num, &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 37c94f76f8..ca1e05c163 100644 --- a/apps/app_queue.c +++ b/apps/app_queue.c @@ -3243,8 +3243,13 @@ static int try_calling(struct queue_ent *qe, const char *options, char *announce if (use_weight) ao2_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); } ao2_lock(qe->parent);