Fix pickup extension channel reference error.
You cannot unref a pointer and then expect to ref it again later. * Fix potential NULL pointer deref if the call pickup search fails. git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@371052 65c4cc65-6c06-0410-ace0-fbb531ad65f3
This commit is contained in:
parent
7709885125
commit
ca481359b9
1 changed files with 18 additions and 6 deletions
|
@ -7718,27 +7718,38 @@ int ast_pickup_call(struct ast_channel *chan)
|
||||||
* Transfer all pickup-able channels to another container-iterator.
|
* Transfer all pickup-able channels to another container-iterator.
|
||||||
* Iterate it to find the oldest channel.
|
* Iterate it to find the oldest channel.
|
||||||
*/
|
*/
|
||||||
targets_it = (struct ao2_iterator *)ast_channel_callback(find_channel_by_group, NULL, chan, OBJ_MULTIPLE);
|
targets_it = (struct ao2_iterator *) ast_channel_callback(find_channel_by_group,
|
||||||
|
NULL, chan, OBJ_MULTIPLE);
|
||||||
|
if (!targets_it) {
|
||||||
|
/* Search really failed. */
|
||||||
|
goto no_pickup_calls;
|
||||||
|
}
|
||||||
|
|
||||||
target = NULL;
|
target = NULL;
|
||||||
while ((candidate = ao2_iterator_next(targets_it))) {
|
while ((candidate = ao2_iterator_next(targets_it))) {
|
||||||
if (!target || ast_tvcmp(ast_channel_creationtime(candidate), ast_channel_creationtime(target)) < 0) {
|
if (!target) {
|
||||||
target = candidate;
|
target = candidate;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (ast_tvcmp(ast_channel_creationtime(candidate), ast_channel_creationtime(target)) < 0) {
|
||||||
|
ast_channel_unref(target);
|
||||||
|
target = candidate;
|
||||||
|
continue;
|
||||||
}
|
}
|
||||||
ast_channel_unref(candidate);
|
ast_channel_unref(candidate);
|
||||||
}
|
}
|
||||||
|
ao2_iterator_destroy(targets_it);
|
||||||
if (target) {
|
if (target) {
|
||||||
/* The found channel must be locked and ref'd. */
|
/* The found channel must be locked and ref'd. */
|
||||||
ast_channel_lock(ast_channel_ref(target));
|
ast_channel_lock(target);
|
||||||
/* Recheck pickup ability */
|
/* Recheck pickup ability */
|
||||||
if (!ast_can_pickup(target)) {
|
if (!ast_can_pickup(target)) {
|
||||||
|
/* Someone else picked it up or the call went away. */
|
||||||
ast_channel_unlock(target);
|
ast_channel_unlock(target);
|
||||||
target = ast_channel_unref(target);/* Bad luck */
|
target = ast_channel_unref(target);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
ao2_iterator_destroy(targets_it);
|
|
||||||
|
|
||||||
if (target) {
|
if (target) {
|
||||||
ast_log(LOG_NOTICE, "pickup %s attempt by %s\n", ast_channel_name(target), ast_channel_name(chan));
|
ast_log(LOG_NOTICE, "pickup %s attempt by %s\n", ast_channel_name(target), ast_channel_name(chan));
|
||||||
|
|
||||||
|
@ -7754,6 +7765,7 @@ int ast_pickup_call(struct ast_channel *chan)
|
||||||
target = ast_channel_unref(target);
|
target = ast_channel_unref(target);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
no_pickup_calls:
|
||||||
if (res < 0) {
|
if (res < 0) {
|
||||||
ast_debug(1, "No call pickup possible... for %s\n", ast_channel_name(chan));
|
ast_debug(1, "No call pickup possible... for %s\n", ast_channel_name(chan));
|
||||||
if (!ast_strlen_zero(pickupfailsound)) {
|
if (!ast_strlen_zero(pickupfailsound)) {
|
||||||
|
|
Loading…
Reference in a new issue