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.
This commit is contained in:
parent
92f4b1a6f1
commit
88d06478d3
@ -191,51 +191,43 @@ static int pa_sound_device_read(pa_handle *p) {
|
|||||||
if((clock_get_monotonic_seconds() - start_time) * 1000 >= timeout_ms)
|
if((clock_get_monotonic_seconds() - start_time) * 1000 >= timeout_ms)
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
if(p->read_data) {
|
if(!p->read_data) {
|
||||||
assert(p->output_index == 0);
|
pa_mainloop_prepare(p->mainloop, 1 * 1000); // 1 ms
|
||||||
memcpy(p->output_data, (const uint8_t*)p->read_data + p->read_index, p->read_length);
|
pa_mainloop_poll(p->mainloop);
|
||||||
p->output_index += p->read_length;
|
pa_mainloop_dispatch(p->mainloop);
|
||||||
p->read_data = NULL;
|
|
||||||
p->read_length = 0;
|
|
||||||
p->read_index = 0;
|
|
||||||
|
|
||||||
if(pa_stream_drop(p->stream) != 0)
|
if(pa_stream_peek(p->stream, &p->read_data, &p->read_length) < 0)
|
||||||
goto fail;
|
goto fail;
|
||||||
}
|
|
||||||
|
|
||||||
pa_mainloop_prepare(p->mainloop, 1 * 1000); // 1 ms
|
if(!p->read_data && p->read_length == 0)
|
||||||
pa_mainloop_poll(p->mainloop);
|
continue;
|
||||||
pa_mainloop_dispatch(p->mainloop);
|
|
||||||
|
|
||||||
if(pa_stream_peek(p->stream, &p->read_data, &p->read_length) < 0)
|
if(!p->read_data && p->read_length > 0) {
|
||||||
goto fail;
|
// 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)
|
if(p->read_length <= 0) {
|
||||||
continue;
|
p->read_data = NULL;
|
||||||
|
if(pa_stream_drop(p->stream) != 0)
|
||||||
|
goto fail;
|
||||||
|
|
||||||
if(!p->read_data && p->read_length > 0) {
|
CHECK_DEAD_GOTO(p, rerror, fail);
|
||||||
// There is a hole in the stream :( drop it. Maybe we should generate silence instead? TODO
|
continue;
|
||||||
if(pa_stream_drop(p->stream) != 0)
|
}
|
||||||
goto fail;
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
if(p->read_length <= 0) {
|
|
||||||
CHECK_DEAD_GOTO(p, rerror, fail);
|
|
||||||
continue;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const size_t space_free_in_output_buffer = p->output_length - p->output_index;
|
const size_t space_free_in_output_buffer = p->output_length - p->output_index;
|
||||||
if(space_free_in_output_buffer < p->read_length) {
|
if(space_free_in_output_buffer < p->read_length) {
|
||||||
assert(p->read_index == 0);
|
memcpy(p->output_data + p->output_index, (const uint8_t*)p->read_data + p->read_index, space_free_in_output_buffer);
|
||||||
memcpy(p->output_data + p->output_index, p->read_data, space_free_in_output_buffer);
|
|
||||||
p->output_index = 0;
|
p->output_index = 0;
|
||||||
p->read_index += space_free_in_output_buffer;
|
p->read_index += space_free_in_output_buffer;
|
||||||
p->read_length -= space_free_in_output_buffer;
|
p->read_length -= space_free_in_output_buffer;
|
||||||
break;
|
break;
|
||||||
} else {
|
} else {
|
||||||
assert(p->read_index == 0);
|
memcpy(p->output_data + p->output_index, (const uint8_t*)p->read_data + p->read_index, p->read_length);
|
||||||
memcpy(p->output_data + p->output_index, p->read_data, p->read_length);
|
|
||||||
p->output_index += p->read_length;
|
p->output_index += p->read_length;
|
||||||
p->read_data = NULL;
|
p->read_data = NULL;
|
||||||
p->read_length = 0;
|
p->read_length = 0;
|
||||||
@ -359,12 +351,12 @@ std::vector<AudioInput> get_pulseaudio_inputs() {
|
|||||||
pa_operation_unref(pa_op);
|
pa_operation_unref(pa_op);
|
||||||
pa_context_disconnect(ctx);
|
pa_context_disconnect(ctx);
|
||||||
pa_context_unref(ctx);
|
pa_context_unref(ctx);
|
||||||
pa_mainloop_free(main_loop);
|
break;
|
||||||
return inputs;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pa_mainloop_iterate(main_loop, 1, NULL);
|
pa_mainloop_iterate(main_loop, 1, NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
pa_mainloop_free(main_loop);
|
pa_mainloop_free(main_loop);
|
||||||
|
return inputs;
|
||||||
}
|
}
|
Loading…
Reference in New Issue
Block a user