mirror of
https://github.com/asterisk/asterisk.git
synced 2025-09-30 10:33:13 +00:00
Merged revisions 67716 via svnmerge from
https://origsvn.digium.com/svn/asterisk/branches/1.4 ................ r67716 | russell | 2007-06-06 11:55:59 -0500 (Wed, 06 Jun 2007) | 13 lines Merged revisions 67715 via svnmerge from https://origsvn.digium.com/svn/asterisk/branches/1.2 ........ r67715 | russell | 2007-06-06 11:40:51 -0500 (Wed, 06 Jun 2007) | 5 lines We have some bug reports showing crashes due to a double free of a channel. Add a sanity check to ast_channel_free() to make sure we don't go on trying to free a channel that wasn't found in the channel list. (issue #8850, and others...) ........ ................ git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@67717 65c4cc65-6c06-0410-ace0-fbb531ad65f3
This commit is contained in:
@@ -729,8 +729,10 @@ struct { \
|
|||||||
used to link entries of this list together.
|
used to link entries of this list together.
|
||||||
\warning The removed entry is \b not freed nor modified in any way.
|
\warning The removed entry is \b not freed nor modified in any way.
|
||||||
*/
|
*/
|
||||||
#define AST_LIST_REMOVE(head, elm, field) do { \
|
#define AST_LIST_REMOVE(head, elm, field) ({ \
|
||||||
|
__typeof(elm) __res = NULL; \
|
||||||
if ((head)->first == (elm)) { \
|
if ((head)->first == (elm)) { \
|
||||||
|
__res = (head)->first; \
|
||||||
(head)->first = (elm)->field.next; \
|
(head)->first = (elm)->field.next; \
|
||||||
if ((head)->last == (elm)) \
|
if ((head)->last == (elm)) \
|
||||||
(head)->last = NULL; \
|
(head)->last = NULL; \
|
||||||
@@ -739,13 +741,15 @@ struct { \
|
|||||||
while (curelm && (curelm->field.next != (elm))) \
|
while (curelm && (curelm->field.next != (elm))) \
|
||||||
curelm = curelm->field.next; \
|
curelm = curelm->field.next; \
|
||||||
if (curelm) { \
|
if (curelm) { \
|
||||||
|
__res = curelm; \
|
||||||
curelm->field.next = (elm)->field.next; \
|
curelm->field.next = (elm)->field.next; \
|
||||||
if ((head)->last == (elm)) \
|
if ((head)->last == (elm)) \
|
||||||
(head)->last = curelm; \
|
(head)->last = curelm; \
|
||||||
} \
|
} \
|
||||||
} \
|
} \
|
||||||
(elm)->field.next = NULL; \
|
(elm)->field.next = NULL; \
|
||||||
} while (0)
|
(__res); \
|
||||||
|
})
|
||||||
|
|
||||||
#define AST_RWLIST_REMOVE AST_LIST_REMOVE
|
#define AST_RWLIST_REMOVE AST_LIST_REMOVE
|
||||||
|
|
||||||
|
@@ -1082,7 +1082,10 @@ void ast_channel_free(struct ast_channel *chan)
|
|||||||
headp=&chan->varshead;
|
headp=&chan->varshead;
|
||||||
|
|
||||||
AST_LIST_LOCK(&channels);
|
AST_LIST_LOCK(&channels);
|
||||||
AST_LIST_REMOVE(&channels, chan, chan_list);
|
if (!AST_LIST_REMOVE(&channels, chan, chan_list)) {
|
||||||
|
AST_LIST_UNLOCK(&channels);
|
||||||
|
ast_log(LOG_ERROR, "Unable to find channel in list to free. Assuming it has already been done.\n");
|
||||||
|
}
|
||||||
/* Lock and unlock the channel just to be sure nobody
|
/* Lock and unlock the channel just to be sure nobody
|
||||||
has it locked still */
|
has it locked still */
|
||||||
ast_channel_lock(chan);
|
ast_channel_lock(chan);
|
||||||
|
Reference in New Issue
Block a user