mirror of
https://github.com/asterisk/asterisk.git
synced 2025-09-30 18:40:46 +00:00
fixes audiohook write crash occuring in chan_spy whisper mode.
After writing to the audiohook list in ast_write(), frames were being freed incorrectly. Under certain conditions this resulted in a double free crash. (closes issue #16133) Reported by: wetwired (closes issue #16045) Reported by: bluecrow76 Patches: issue16045.diff uploaded by dvossel (license 671) Tested by: bluecrow76, dvossel, habile git-svn-id: https://origsvn.digium.com/svn/asterisk/branches/1.4@228692 65c4cc65-6c06-0410-ace0-fbb531ad65f3
This commit is contained in:
@@ -2949,6 +2949,11 @@ int ast_write(struct ast_channel *chan, struct ast_frame *fr)
|
|||||||
|
|
||||||
if (chan->audiohooks) {
|
if (chan->audiohooks) {
|
||||||
struct ast_frame *prev = NULL, *new_frame, *cur, *dup;
|
struct ast_frame *prev = NULL, *new_frame, *cur, *dup;
|
||||||
|
int freeoldlist = 0;
|
||||||
|
|
||||||
|
if (f != fr) {
|
||||||
|
freeoldlist = 1;
|
||||||
|
}
|
||||||
|
|
||||||
/* Since ast_audiohook_write may return a new frame, and the cur frame is
|
/* Since ast_audiohook_write may return a new frame, and the cur frame is
|
||||||
* an item in a list of frames, create a new list adding each cur frame back to it
|
* an item in a list of frames, create a new list adding each cur frame back to it
|
||||||
@@ -2959,13 +2964,16 @@ int ast_write(struct ast_channel *chan, struct ast_frame *fr)
|
|||||||
/* if this frame is different than cur, preserve the end of the list,
|
/* if this frame is different than cur, preserve the end of the list,
|
||||||
* free the old frames, and set cur to be the new frame */
|
* free the old frames, and set cur to be the new frame */
|
||||||
if (new_frame != cur) {
|
if (new_frame != cur) {
|
||||||
|
|
||||||
/* doing an ast_frisolate here seems silly, but we are not guaranteed the new_frame
|
/* doing an ast_frisolate here seems silly, but we are not guaranteed the new_frame
|
||||||
* isn't part of local storage, meaning if ast_audiohook_write is called multiple
|
* isn't part of local storage, meaning if ast_audiohook_write is called multiple
|
||||||
* times it may override the previous frame we got from it unless we dup it */
|
* times it may override the previous frame we got from it unless we dup it */
|
||||||
if ((dup = ast_frisolate(new_frame))) {
|
if ((dup = ast_frisolate(new_frame))) {
|
||||||
AST_LIST_NEXT(dup, frame_list) = AST_LIST_NEXT(cur, frame_list);
|
AST_LIST_NEXT(dup, frame_list) = AST_LIST_NEXT(cur, frame_list);
|
||||||
ast_frfree(new_frame);
|
if (freeoldlist) {
|
||||||
|
AST_LIST_NEXT(cur, frame_list) = NULL;
|
||||||
ast_frfree(cur);
|
ast_frfree(cur);
|
||||||
|
}
|
||||||
cur = dup;
|
cur = dup;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user