[pulseaudio-discuss] [PATCH] echo-cancel: Avoid segfaults due to invalid master sink or source

Georg Chini georg at chini.tk
Mon Apr 24 17:33:15 UTC 2017


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



More information about the pulseaudio-discuss mailing list