From 88d06478d31759f8d0830c432f9022bd9ccd1f96 Mon Sep 17 00:00:00 2001 From: dec05eba Date: Fri, 7 Oct 2022 03:44:54 +0200 Subject: Fix crash caused by invalid memory write when recording audio In some scenarios memcpy can write to 8 bytes (or more?) over the buffer end. Thanks to Guilherme for reporting the issue and testing the fix. --- src/sound.cpp | 56 ++++++++++++++++++++++++-------------------------------- 1 file changed, 24 insertions(+), 32 deletions(-) (limited to 'src') diff --git a/src/sound.cpp b/src/sound.cpp index e4086b1..794d3ea 100644 --- a/src/sound.cpp +++ b/src/sound.cpp @@ -191,51 +191,43 @@ static int pa_sound_device_read(pa_handle *p) { if((clock_get_monotonic_seconds() - start_time) * 1000 >= timeout_ms) return -1; - if(p->read_data) { - assert(p->output_index == 0); - memcpy(p->output_data, (const uint8_t*)p->read_data + p->read_index, p->read_length); - p->output_index += p->read_length; - p->read_data = NULL; - p->read_length = 0; - p->read_index = 0; + if(!p->read_data) { + pa_mainloop_prepare(p->mainloop, 1 * 1000); // 1 ms + pa_mainloop_poll(p->mainloop); + pa_mainloop_dispatch(p->mainloop); - if(pa_stream_drop(p->stream) != 0) + if(pa_stream_peek(p->stream, &p->read_data, &p->read_length) < 0) goto fail; - } - - pa_mainloop_prepare(p->mainloop, 1 * 1000); // 1 ms - pa_mainloop_poll(p->mainloop); - pa_mainloop_dispatch(p->mainloop); - if(pa_stream_peek(p->stream, &p->read_data, &p->read_length) < 0) - goto fail; + if(!p->read_data && p->read_length == 0) + continue; - if(!p->read_data && p->read_length == 0) - continue; + if(!p->read_data && p->read_length > 0) { + // There is a hole in the stream :( drop it. Maybe we should generate silence instead? TODO + if(pa_stream_drop(p->stream) != 0) + goto fail; + continue; + } - if(!p->read_data && p->read_length > 0) { - // There is a hole in the stream :( drop it. Maybe we should generate silence instead? TODO - if(pa_stream_drop(p->stream) != 0) - goto fail; - continue; - } + if(p->read_length <= 0) { + p->read_data = NULL; + if(pa_stream_drop(p->stream) != 0) + goto fail; - if(p->read_length <= 0) { - CHECK_DEAD_GOTO(p, rerror, fail); - continue; + CHECK_DEAD_GOTO(p, rerror, fail); + continue; + } } const size_t space_free_in_output_buffer = p->output_length - p->output_index; if(space_free_in_output_buffer < p->read_length) { - assert(p->read_index == 0); - memcpy(p->output_data + p->output_index, p->read_data, space_free_in_output_buffer); + memcpy(p->output_data + p->output_index, (const uint8_t*)p->read_data + p->read_index, space_free_in_output_buffer); p->output_index = 0; p->read_index += space_free_in_output_buffer; p->read_length -= space_free_in_output_buffer; break; } else { - assert(p->read_index == 0); - memcpy(p->output_data + p->output_index, p->read_data, p->read_length); + memcpy(p->output_data + p->output_index, (const uint8_t*)p->read_data + p->read_index, p->read_length); p->output_index += p->read_length; p->read_data = NULL; p->read_length = 0; @@ -359,12 +351,12 @@ std::vector get_pulseaudio_inputs() { pa_operation_unref(pa_op); pa_context_disconnect(ctx); pa_context_unref(ctx); - pa_mainloop_free(main_loop); - return inputs; + break; } pa_mainloop_iterate(main_loop, 1, NULL); } pa_mainloop_free(main_loop); + return inputs; } \ No newline at end of file -- cgit v1.2.3