diff --git a/apps/app_dial.c b/apps/app_dial.c index 9c2664aa6b..6d0c6a6e7f 100644 --- a/apps/app_dial.c +++ b/apps/app_dial.c @@ -1600,8 +1600,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 7f01445df5..aef06aa2d6 100644 --- a/apps/app_queue.c +++ b/apps/app_queue.c @@ -3252,8 +3252,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);