Merge "autochan/mixmonitor/chanspy: Fix unsafe channel locking and references." into 13

This commit is contained in:
zuul
2017-03-21 19:47:25 -05:00
committed by Gerrit Code Review
4 changed files with 85 additions and 34 deletions

View File

@@ -48,15 +48,18 @@ struct ast_autochan *ast_autochan_setup(struct ast_channel *chan)
if (!(autochan = ast_calloc(1, sizeof(*autochan)))) {
return NULL;
}
ast_mutex_init(&autochan->lock);
autochan->chan = ast_channel_ref(chan);
ast_channel_lock(autochan->chan); /* autochan is still private, no need for ast_autochan_channel_lock() */
ast_debug(1, "Created autochan %p to hold channel %s (%p)\n",
autochan, ast_channel_name(chan), chan);
/* autochan is still private, no need for ast_autochan_channel_lock() */
ast_channel_lock(autochan->chan);
AST_LIST_INSERT_TAIL(ast_channel_autochans(autochan->chan), autochan, list);
ast_channel_unlock(autochan->chan);
ast_debug(1, "Created autochan %p to hold channel %s (%p)\n", autochan, ast_channel_name(chan), chan);
return autochan;
}
@@ -77,6 +80,8 @@ void ast_autochan_destroy(struct ast_autochan *autochan)
autochan->chan = ast_channel_unref(autochan->chan);
ast_mutex_destroy(&autochan->lock);
ast_free(autochan);
}
@@ -86,13 +91,16 @@ void ast_autochan_new_channel(struct ast_channel *old_chan, struct ast_channel *
AST_LIST_APPEND_LIST(ast_channel_autochans(new_chan), ast_channel_autochans(old_chan), list);
/* Deadlock avoidance is not needed since the channels are already locked. */
AST_LIST_TRAVERSE(ast_channel_autochans(new_chan), autochan, list) {
ast_mutex_lock(&autochan->lock);
if (autochan->chan == old_chan) {
autochan->chan = ast_channel_unref(old_chan);
autochan->chan = ast_channel_ref(new_chan);
ast_channel_unref(old_chan);
ast_debug(1, "Autochan %p used to hold channel %s (%p) but now holds channel %s (%p)\n",
autochan, ast_channel_name(old_chan), old_chan, ast_channel_name(new_chan), new_chan);
}
ast_mutex_unlock(&autochan->lock);
}
}