[pulseaudio-discuss] [PATCH] virtual sources and sinks: Fix possible segfault due to invalid master sink or source

Georg Chini georg at chini.tk
Mon Apr 24 19:26:11 UTC 2017


There are several places in the virtual sinks and sources 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.
---
 src/modules/module-ladspa-sink.c           | 11 +++++++----
 src/modules/module-remap-sink.c            |  6 ++++--
 src/modules/module-remap-source.c          |  3 ++-
 src/modules/module-virtual-sink.c          | 12 ++++++++----
 src/modules/module-virtual-source.c        |  9 ++++++---
 src/modules/module-virtual-surround-sink.c | 12 ++++++++----
 6 files changed, 35 insertions(+), 18 deletions(-)

diff --git a/src/modules/module-ladspa-sink.c b/src/modules/module-ladspa-sink.c
index 86ab4a6f..cc2141b3 100644
--- a/src/modules/module-ladspa-sink.c
+++ b/src/modules/module-ladspa-sink.c
@@ -387,7 +387,7 @@ static int sink_set_state_cb(pa_sink *s, pa_sink_state_t state) {
     pa_assert_se(u = s->userdata);
 
     if (!PA_SINK_IS_LINKED(state) ||
-            !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)))
         return 0;
 
     pa_sink_input_cork(u->sink_input, state == PA_SINK_SUSPENDED);
@@ -402,7 +402,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;
 
     /* Just hand this one over to the master sink */
@@ -419,7 +420,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;
 
     /* Just hand this one over to the master sink */
@@ -436,7 +438,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);
diff --git a/src/modules/module-remap-sink.c b/src/modules/module-remap-sink.c
index 534874d7..7bbd5429 100644
--- a/src/modules/module-remap-sink.c
+++ b/src/modules/module-remap-sink.c
@@ -125,7 +125,8 @@ static void sink_request_rewind(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_sink_input_request_rewind(u->sink_input, s->thread_info.rewind_nbytes, true, false, false);
@@ -139,7 +140,8 @@ static void sink_update_requested_latency(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;
 
     /* Just hand this one over to the master sink */
diff --git a/src/modules/module-remap-source.c b/src/modules/module-remap-source.c
index 25772ecd..7221ce62 100644
--- a/src/modules/module-remap-source.c
+++ b/src/modules/module-remap-source.c
@@ -133,7 +133,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.");
diff --git a/src/modules/module-virtual-sink.c b/src/modules/module-virtual-sink.c
index 6175ca8e..6695c4e9 100644
--- a/src/modules/module-virtual-sink.c
+++ b/src/modules/module-virtual-sink.c
@@ -137,7 +137,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;
 
     /* Just hand this one over to the master sink */
@@ -154,7 +155,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;
 
     /* Just hand this one over to the master sink */
@@ -171,7 +173,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);
@@ -185,7 +188,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);
diff --git a/src/modules/module-virtual-source.c b/src/modules/module-virtual-source.c
index dd0b40e1..e9f2c266 100644
--- a/src/modules/module-virtual-source.c
+++ b/src/modules/module-virtual-source.c
@@ -219,7 +219,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;
 
     /* Just hand this one over to the master source */
@@ -236,7 +237,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);
@@ -250,7 +252,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);
diff --git a/src/modules/module-virtual-surround-sink.c b/src/modules/module-virtual-surround-sink.c
index 94ea9f4a..42b61a38 100644
--- a/src/modules/module-virtual-surround-sink.c
+++ b/src/modules/module-virtual-surround-sink.c
@@ -165,7 +165,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;
 
     /* Just hand this one over to the master sink */
@@ -182,7 +183,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;
 
     /* Just hand this one over to the master sink */
@@ -199,7 +201,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);
@@ -213,7 +216,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