diff options
author | Richard Mudgett <rmudgett@digium.com> | 2017-11-14 18:00:55 -0600 |
---|---|---|
committer | Richard Mudgett <rmudgett@digium.com> | 2017-11-15 17:06:53 -0500 |
commit | fcec0fc644e5853799b061ab2876dcac9057d8a1 (patch) | |
tree | 29458084061d7f63bf95557cc6343cabc9ce5bf3 | |
parent | b8fafd6806ab2684d547074b25a56dd152097341 (diff) |
audiohook.c: Fix freeing a frame and still using it.
Memory corruption happened to the media frame caches when an audio hook
freed a frame when it shouldn't. I think the freed frame was because a
jitter buffer interpolated a missing frame and the audio hook
unconditionally freed it.
* Made audiohook.c:audio_audiohook_write_list() not free an interpolated
frame if it is the same frame as what was passed into the routine.
* Made plc.c:normalise_history() use memmove() instead of memcpy() on a
memory block that could overlap. Found by valgrind investigating this
issue.
ASTERISK-27238
ASTERISK-27412
Change-Id: I548d86894281fc4529aefeb9f161f2131ecc6fde
-rw-r--r-- | main/audiohook.c | 4 | ||||
-rw-r--r-- | main/plc.c | 2 |
2 files changed, 4 insertions, 2 deletions
diff --git a/main/audiohook.c b/main/audiohook.c index 2cba2de6e..04a379fef 100644 --- a/main/audiohook.c +++ b/main/audiohook.c @@ -950,7 +950,9 @@ static struct ast_frame *audio_audiohook_write_list(struct ast_channel *chan, st * rely on actual media being present to do things. */ if (!middle_frame->data.ptr) { - ast_frfree(middle_frame); + if (middle_frame != start_frame) { + ast_frfree(middle_frame); + } return start_frame; } diff --git a/main/plc.c b/main/plc.c index b649357dc..739f7276d 100644 --- a/main/plc.c +++ b/main/plc.c @@ -96,7 +96,7 @@ static void normalise_history(plc_state_t *s) if (s->buf_ptr == 0) return; memcpy(tmp, s->history, sizeof(int16_t)*s->buf_ptr); - memcpy(s->history, s->history + s->buf_ptr, sizeof(int16_t) * (PLC_HISTORY_LEN - s->buf_ptr)); + memmove(s->history, s->history + s->buf_ptr, sizeof(int16_t) * (PLC_HISTORY_LEN - s->buf_ptr)); memcpy(s->history + PLC_HISTORY_LEN - s->buf_ptr, tmp, sizeof(int16_t) * s->buf_ptr); s->buf_ptr = 0; } |