There are several places in module-echo-cancel where a segfault is possible when the master sink or source is invalid. This patch checks for the validity of master source or sink and lets the functions just return if it is invalid. Other virtual sinks and sources will be fixed in a separate patch. --- src/modules/echo-cancel/module-echo-cancel.c | 24 ++++++++++++++++-------- 1 file changed, 16 insertions(+), 8 deletions(-) diff --git a/src/modules/echo-cancel/module-echo-cancel.c b/src/modules/echo-cancel/module-echo-cancel.c index 7e7290e6..75473a5a 100644 --- a/src/modules/echo-cancel/module-echo-cancel.c +++ b/src/modules/echo-cancel/module-echo-cancel.c @@ -525,7 +525,8 @@ static void source_update_requested_latency_cb(pa_source *s) { pa_assert_se(u = s->userdata); if (!PA_SOURCE_IS_LINKED(u->source->thread_info.state) || - !PA_SOURCE_OUTPUT_IS_LINKED(u->source_output->thread_info.state)) + !PA_SOURCE_OUTPUT_IS_LINKED(u->source_output->thread_info.state) || + !u->source_output->source) return; pa_log_debug("Source update requested latency"); @@ -546,7 +547,8 @@ static void sink_update_requested_latency_cb(pa_sink *s) { pa_assert_se(u = s->userdata); if (!PA_SINK_IS_LINKED(u->sink->thread_info.state) || - !PA_SINK_INPUT_IS_LINKED(u->sink_input->thread_info.state)) + !PA_SINK_INPUT_IS_LINKED(u->sink_input->thread_info.state) || + !u->sink_input->sink) return; pa_log_debug("Sink update requested latency"); @@ -566,7 +568,8 @@ static void sink_request_rewind_cb(pa_sink *s) { pa_assert_se(u = s->userdata); if (!PA_SINK_IS_LINKED(u->sink->thread_info.state) || - !PA_SINK_INPUT_IS_LINKED(u->sink_input->thread_info.state)) + !PA_SINK_INPUT_IS_LINKED(u->sink_input->thread_info.state) || + !u->sink_input->sink) return; pa_log_debug("Sink request rewind %lld", (long long) s->thread_info.rewind_nbytes); @@ -584,7 +587,8 @@ static void source_set_volume_cb(pa_source *s) { pa_assert_se(u = s->userdata); if (!PA_SOURCE_IS_LINKED(pa_source_get_state(s)) || - !PA_SOURCE_OUTPUT_IS_LINKED(pa_source_output_get_state(u->source_output))) + !PA_SOURCE_OUTPUT_IS_LINKED(pa_source_output_get_state(u->source_output)) || + !u->source_output->source) return; pa_source_output_set_volume(u->source_output, &s->real_volume, s->save_volume, true); @@ -598,7 +602,8 @@ static void sink_set_volume_cb(pa_sink *s) { pa_assert_se(u = s->userdata); if (!PA_SINK_IS_LINKED(pa_sink_get_state(s)) || - !PA_SINK_INPUT_IS_LINKED(pa_sink_input_get_state(u->sink_input))) + !PA_SINK_INPUT_IS_LINKED(pa_sink_input_get_state(u->sink_input)) || + !u->sink_input->sink) return; pa_sink_input_set_volume(u->sink_input, &s->real_volume, s->save_volume, true); @@ -613,7 +618,8 @@ static void source_get_volume_cb(pa_source *s) { pa_assert_se(u = s->userdata); if (!PA_SOURCE_IS_LINKED(pa_source_get_state(s)) || - !PA_SOURCE_OUTPUT_IS_LINKED(pa_source_output_get_state(u->source_output))) + !PA_SOURCE_OUTPUT_IS_LINKED(pa_source_output_get_state(u->source_output)) || + !u->source_output->source) return; pa_source_output_get_volume(u->source_output, &v, true); @@ -634,7 +640,8 @@ static void source_set_mute_cb(pa_source *s) { pa_assert_se(u = s->userdata); if (!PA_SOURCE_IS_LINKED(pa_source_get_state(s)) || - !PA_SOURCE_OUTPUT_IS_LINKED(pa_source_output_get_state(u->source_output))) + !PA_SOURCE_OUTPUT_IS_LINKED(pa_source_output_get_state(u->source_output)) || + !u->source_output->source) return; pa_source_output_set_mute(u->source_output, s->muted, s->save_muted); @@ -648,7 +655,8 @@ static void sink_set_mute_cb(pa_sink *s) { pa_assert_se(u = s->userdata); if (!PA_SINK_IS_LINKED(pa_sink_get_state(s)) || - !PA_SINK_INPUT_IS_LINKED(pa_sink_input_get_state(u->sink_input))) + !PA_SINK_INPUT_IS_LINKED(pa_sink_input_get_state(u->sink_input)) || + !u->sink_input->sink) return; pa_sink_input_set_mute(u->sink_input, s->muted, s->save_muted); -- 2.11.0