audiohook.c: Fix freeing a frame and still using it.
authorRichard Mudgett <rmudgett@digium.com>
Wed, 15 Nov 2017 00:00:55 +0000 (18:00 -0600)
committerRichard Mudgett <rmudgett@digium.com>
Wed, 15 Nov 2017 22:07:07 +0000 (17:07 -0500)
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

main/audiohook.c
main/plc.c

index 2cba2de..04a379f 100644 (file)
@@ -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;
        }
 
index b649357..739f727 100644 (file)
@@ -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;
 }